部队中总共有N个士兵,每个士兵有各自的能力指数Xi,在一次演练中,指挥部确定了M个需要防守的地点,指挥部将选择M个士兵依次进入指定地点进行防守任务,获得的参考指数即为M个士兵的能力之和。随着时间的推移,指挥部将下达Q个指令来替换M个进行防守的士兵们,每个参加完防守任务的士兵由于疲惫等原因能力指数将下降1。现在士兵们排成一排,请你计算出每次进行防守的士兵的参考指数。
输入包含多组数据。
输入第一行有两个整数N,M,Q(1<=N<=100000,1<=M<=1000,1<=Q<=100000),第二行N个整数表示每个士兵对应的能力指数Xi(1<=Xi<=1000)。
接下来Q行,每行一个整数X,表示在原始队列中以X为起始的M个士兵替换之前的士兵进行防守。(1<=X<=N-M+1)
对于30%的数据1<=M,N,Q<=1000。
输出Q行,每行一个整数,为每次指令执行之后进行防守的士兵参考指数。
#include<iostream> #include<stdio.h> #include<string.h> #define maxx 100002 using namespace std; struct node{int l,r,color,sum;}tree[maxx*4]; void build(int left,int right,int k) { tree[k].l=left; tree[k].r=right; tree[k].color=0; if(left==right) { scanf("%d",&tree[k].sum); return; } int m; m=(left+right)/2; build(left,m,k*2); build(m+1,right,k*2+1); tree[k].sum=tree[k*2].sum+tree[k*2+1].sum; } void pushdown(int k) { tree[k*2].sum-=(tree[k*2].r-tree[k*2].l+1)*tree[k].color; tree[k*2+1].sum-=(tree[k*2+1].r-tree[k*2+1].l+1)*tree[k].color; tree[k*2].color+=tree[k].color; tree[k*2+1].color+=tree[k].color; } int sum(int left,int right,int k) { if(tree[k].l==left&&tree[k].r==right) return tree[k].sum; if(tree[k].color) { pushdown(k); tree[k].color = 0; } int m; m=(tree[k].l+tree[k].r)/2; if(right<=m) return sum(left,right,k*2); if(left>=m+1) return sum(left,right,k*2+1); return sum(left,m,k*2)+sum(m+1,right,k*2+1); } void update(int left,int right,int k) { if(tree[k].l==left&&tree[k].r==right) { tree[k].sum-=tree[k].r-tree[k].l+1; tree[k].color++; return ; } int m; m=(tree[k].l+tree[k].r)/2; if(right<=m) update(left,right,k*2); else if(left>=m+1) update(left,right,k*2+1); else { update(left,m,k*2); update(m+1,right,k*2+1); }tree[k].sum=tree[k*2].sum+tree[k*2+1].sum; } int main() { int i,j,n,m,t,q,a,b; while(~scanf("%d%d%d",&n,&m,&q)) { build(1,n,1); while(q--) { //printf("1"); scanf("%d",&a); //printf(" er "); b=a+m-1; printf("%d\n",sum(a,b,1));//printf("sdfd"); update(a,b,1);//printf("okok"); } } }
fzu 2171 线段树 lazy标记,布布扣,bubuko.com
原文:http://www.cnblogs.com/assult/p/3709870.html