码迷,mamicode.com
首页 > 其他好文 > 详细

士兵杀敌(三)简单线段树

时间:2016-05-16 23:20:57      阅读:258      评论:0      收藏:0      [点我收藏+]

标签:

题目描述

南将军统率着N个士兵,士兵分别编号为1~N,南将军经常爱拿某一段编号内杀敌数最高的人与杀敌数最低的人进行比较,计算出两个人的杀敌数差值,用这种方法一方面能鼓舞杀敌数高的人,另一方面也算是批评杀敌数低的人,起到了很好的效果。

所以,南将军经常问军师小工第i号士兵到第j号士兵中,杀敌数最高的人与杀敌数最低的人之间军功差值是多少。

现在,请你写一个程序,帮小工回答南将军每次的询问吧。

注意,南将军可能询问很多次。

 

输入

只有一组测试数据
第一行是两个整数N,Q,其中N表示士兵的总数。Q表示南将军询问的次数。(1<N<=100000,1<Q<=1000000)
随后的一行有N个整数Vi(0<=Vi<100000000),分别表示每个人的杀敌数。
再之后的Q行,每行有两个正正数m,n,表示南将军询问的是第m号士兵到第n号士兵。
 

输出

对于每次询问,输出第m号士兵到第n号士兵之间所有士兵杀敌数的最大值与最小值的差。
 

样例输入

5 2
1 2 6 9 3
1 2
2 4

样例输出

1
7

来源

 

小学弟说不会,自己就写了一发,半年没写线段树了啊....写的好搓...别看了...

 

题解:

  1 #include <vector>
  2 #include <map>
  3 #include <set>
  4 #include <algorithm>
  5 #include <iostream>
  6 #include <cstdio>
  7 #include <cmath>
  8 #include <cstdlib>
  9 #include <string>
 10 #include <cstring>
 11 #include <queue>
 12 using namespace std;
 13 
 14 const int maxn = 100010 , INF = -214748364 , INFF = 0x3f3f3f3f;
 15 int a[maxn], b[4*maxn], c[4*maxn] , A, B;       
 16 
 17 void update(int o, int L, int R)    
 18 {
 19     if(L == R)     
 20         b[o] = B;
 21     else
 22     {
 23         int M = L + (R - L) / 2;
 24         if(A <= M)     
 25             update(2*o, L, M);
 26         else    
 27             update(2*o+1, M+1, R);
 28         b[o] = max(b[2*o], b[2*o+1]);
 29     }
 30 }
 31 
 32 int query(int o, int L, int R)      
 33 {
 34     if(A <= L && R <= B)
 35        return c[o];
 36     int M = L + (R - L) / 2, ans = INF;
 37     if(A <= M)   
 38         ans = max(ans, query(2*o, L, M));
 39     if(B > M)    
 40         ans = max(ans, query(2*o+1, M+1, R));
 41     return ans;
 42 }
 43 
 44 int qquery(int o, int L, int R)      
 45 {
 46     if(A <= L && R <= B)
 47        return b[o];
 48     int M = L + (R - L) / 2, ans = INFF;
 49     if(A <= M)   
 50         ans = min(ans, qquery(2*o, L, M));
 51     if(B > M)    
 52         ans = min(ans, qquery(2*o+1, M+1, R));
 53     return ans;
 54 }
 55 
 56 void build(int o, int L, int R)    
 57 {
 58 
 59     if(L == R)
 60     {
 61         b[o] = a[L];
 62         return;
 63     }
 64     int M = L + (R - L) / 2;
 65     if(L <= M)     
 66         build(2*o, L, M);
 67     if(R > M)      
 68         build(2*o+1, M+1, R);
 69     b[o]=min(b[2*o], b[2*o+1]);
 70 
 71 }
 72 
 73 void build1(int o, int L, int R)    
 74 {
 75 
 76     if(L == R)
 77     {
 78         c[o] = a[L];
 79         return;
 80     }
 81     int M = L + (R - L) / 2;
 82     if(L <= M)     
 83         build1(2*o, L, M);
 84     if(R > M)      
 85         build1(2*o+1, M+1, R);
 86     c[o]=max(c[2*o], c[2*o+1]);
 87 
 88 }
 89 
 90 int main()
 91 {
 92     int N, M;
 93     while(~scanf("%d%d\n", &N, &M))
 94     {
 95         b[0]=INFF;
 96         for(int i = 1; i <= N; i++) scanf("%d", &a[i]);
 97         build(1, 1, N);
 98         build1(1, 1, N);
 99         while(M--)
100         {
101             scanf("%d%d", &A, &B);
102             
103             int minn= qquery(1, 1, N);
104             
105             int maxx= query(1, 1, N);
106             printf("%d\n",maxx-minn);
107         }
108     }
109     return 0;
110 }

 

士兵杀敌(三)简单线段树

标签:

原文地址:http://www.cnblogs.com/wangmengmeng/p/5499879.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!