【模板】南阳理工--108 士兵杀敌(一)
描述
南将军手下有N个士兵,分别编号1到N,这些士兵的杀敌数都是已知的。
小工是南将军手下的军师,南将军现在想知道第m号到第n号士兵的总杀敌数,请你帮助小工来回答南将军吧。
注意,南将军可能会问很多次问题。
- 输入
- 只有一组测试数据
第一行是两个整数N,M,其中N表示士兵的个数(1<N<1000000),M表示南将军询问的次数(1<M<100000)
随后的一行是N个整数,ai表示第i号士兵杀敌数目。(0<=ai<=100)
随后的M行每行有两个整数m,n,表示南将军想知道第m号到第n号士兵的总杀敌数(1<=m,n<=N)。 - 输出
- 对于每一个询问,输出总杀敌数
每个输出占一行 - 样例输入
-
5 2 1 2 3 4 5 1 3 2 4
- 样例输出
-
6 9
1 #include<cstdio> 2 struct Note 3 { 4 int l,r,sum; 5 }tree[1000005*4]; //乘以4,防止超限 6 void Pushup(int o) 7 { 8 tree[o].sum=tree[o*2].sum+tree[o*2+1].sum; 9 } 10 void Build(int o,int l,int r) //建树 11 { 12 tree[o].l=l; 13 tree[o].r=r; 14 if(l==r) //递归终止 15 { 16 int t; 17 scanf("%d",&t); //输入数据 18 tree[o].sum=t; 19 return; 20 } 21 int mid=(l+r)/2; 22 Build(o*2,l,mid); //建左子树 23 Build(o*2+1,mid+1,r); //建右子树 24 Pushup(o); //更新节点的值 25 26 } 27 int QuerySum(int o,int l,int r,int x,int y)//查找x到y的和 28 { 29 if(l==x&&r==y) 30 { 31 return tree[o].sum; 32 } 33 int mid=(l+r)/2; 34 if(y<=mid) 35 return QuerySum(o*2,l,mid,x,y); //全在左边 36 else if(x>mid) 37 return QuerySum(o*2+1,mid+1,r,x,y); //全在右边 38 else 39 return QuerySum(o*2,l,mid,x,mid)+QuerySum(o*2+1,mid+1,r,mid+1,y); //左右两边都有 40 } 41 int main() 42 { 43 int n,m,x,y; 44 scanf("%d %d",&n,&m); 45 Build(1,1,n); 46 for(int i=1;i<=m;i++) 47 { 48 scanf("%d %d",&x,&y); 49 printf("%d\n", QuerySum(1,1,n,x,y)); //输出x到y和的结果 50 51 } 52 53 54 return 0; 55 }