士兵杀敌简单线段树
Posted C-DmLy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了士兵杀敌简单线段树相关的知识,希望对你有一定的参考价值。
题目描述
南将军统率着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号士兵。
第一行是两个整数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 }
以上是关于士兵杀敌简单线段树的主要内容,如果未能解决你的问题,请参考以下文章