部队中总共有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行,每行一个整数,为每次指令执行之后进行防守的士兵参考指数。
线段树区间修改,注意延迟标记,修改函数和查询函数的参数是不能改的啊!
延迟标记:
每个节点新增加一个标记,记录这个节点是否进行了某种修改(这种修改操作会影响其子节点),对于任意区间的修改,我们先按照区间查询的方式将其划分成线段树中的节点,然后修改这些节点的信息,并给这些节点标记上代表这种修改操作的标记。在修改和查询的时候,如果我们到了一个节点p,并且决定考虑其子节点,那么我们就要看节点p是否被标记,如果有,就要按照标记修改其子节点的信息,并且给子节点都标上相同的标记,同时消掉节点p的标记。
1 #include<cstdio> 2 #include<cstring> 3 #include<stdlib.h> 4 #include<algorithm> 5 using namespace std; 6 const int MAXN=100000+10; 7 int b[MAXN*4]; 8 struct node 9 { 10 int l,r; 11 int num; 12 int col; 13 int mid() 14 { 15 return (l+r)/2; 16 } 17 }a[MAXN*5]; 18 19 void pushup(int step) 20 { 21 a[step].num=a[step*2].num+a[step*2+1].num; 22 } 23 24 void pushdown(int x,int step) 25 { 26 if(a[step].col!=0) 27 { 28 a[step*2+1].col+=a[step].col; 29 a[step*2].col+=a[step].col; 30 a[step*2].num+=a[step].col*(x-(x/2)); 31 a[step*2+1].num+=a[step].col*((x/2)); 32 a[step].col=0; 33 } 34 } 35 36 void btree(int l,int r,int step) 37 { 38 a[step].l=l; 39 a[step].r=r; 40 a[step].col=0; 41 if(l==r) 42 { 43 a[step].num=b[l]; 44 return ; 45 } 46 int mid=a[step].mid(); 47 btree(l,mid,step*2); 48 btree(mid+1,r,step*2+1); 49 pushup(step); 50 } 51 52 void ptree(int l,int r,int val,int step) 53 { 54 if(l<=a[step].l&&a[step].r<=r) 55 { 56 a[step].col+=val; 57 a[step].num+=val*(a[step].r-a[step].l+1); 58 return ; 59 } 60 pushdown(a[step].r-a[step].l+1,step); 61 int mid=a[step].mid(); 62 if(l>mid) 63 ptree(l,r,val,step*2+1); 64 else if(r<=mid) 65 ptree(l,r,val,step*2); 66 else 67 { 68 ptree(l,r,val,step*2); 69 ptree(l,r,val,step*2+1); 70 } 71 pushup(step); 72 } 73 74 int fintree(int l,int r,int step) 75 { 76 if(l<=a[step].l&&a[step].r<=r) 77 return a[step].num; 78 pushdown(a[step].r-a[step].l+1,step); 79 int mid=a[step].mid(); 80 if(l>mid) 81 return fintree(l,r,step*2+1); 82 else if(r<=mid) 83 return fintree(l,r,step*2); 84 else 85 return fintree(l,r,step*2)+fintree(l,r,step*2+1); 86 } 87 88 int main() 89 { 90 int n,m,kase,num; 91 while(scanf("%d %d %d",&n,&m,&kase)!=EOF) 92 { 93 for(int i=1;i<=n;i++) 94 scanf("%d",&b[i]); 95 btree(1,n,1); 96 while(kase--) 97 { 98 scanf("%d",&num); 99 int ans=fintree(num,num+m-1,1); 100 printf("%d\n",ans); 101 ptree(num,num+m-1,-1,1); 102 } 103 } 104 return 0; 105 }