fzu 2171 防守阵地 II(线段树,成段更新,查询一段区间和)

来源:互联网 发布:魁拔和大圣归来知乎 编辑:程序博客网 时间:2024/04/28 23:31
Problem 2171 防守阵地 II

Accept: 124    Submit: 487
Time Limit: 3000 mSec    Memory Limit : 32768 KB

 Problem Description

部队中总共有N个士兵,每个士兵有各自的能力指数Xi,在一次演练中,指挥部确定了M个需要防守的地点,指挥部将选择M个士兵依次进入指定地点进行防守任务,获得的参考指数即为M个士兵的能力之和。随着时间的推移,指挥部将下达Q个指令来替换M个进行防守的士兵们,每个参加完防守任务的士兵由于疲惫等原因能力指数将下降1。现在士兵们排成一排,请你计算出每次进行防守的士兵的参考指数。

 Input

输入包含多组数据。

输入第一行有两个整数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。

 Output

输出Q行,每行一个整数,为每次指令执行之后进行防守的士兵参考指数。

 Sample Input

5 3 32 1 3 1 4123

 Sample Output

635
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#include<cstdlib>#include<map>#include<set>#include<queue>#include<stack>#define N 100010#define INF -9999999using namespace std;struct node{    int l,r;    int sum,cha;}tree[N*4];int a[N];void buildtree(int l ,int r ,int n){    int mid=(l+r)>>1;    tree[n].l=l;    tree[n].r=r;    tree[n].cha=0;    if(l==r)    {        tree[n].sum=a[l];        return ;    }    buildtree(l,mid,n*2);    buildtree(mid+1,r,n*2+1);    tree[n].sum=tree[n*2].sum+tree[n*2+1].sum;}void pushdown(int n){    tree[2*n].sum-=(tree[2*n].r-tree[2*n].l+1)*tree[n].cha;    tree[2*n+1].sum-=(tree[2*n+1].r-tree[2*n+1].l+1)*tree[n].cha;    tree[2*n].cha+=tree[n].cha;    tree[2*n+1].cha+=tree[n].cha;}int getsum(int x , int y ,int n){    int mid=(tree[n].l+tree[n].r)>>1;    if(x==tree[n].l&&y==tree[n].r)    {        return tree[n].sum;    }    if(tree[n].cha)    {        pushdown(n);        tree[n].cha=0;    }    if(y<=mid)        return getsum(x,y,2*n);    else if(x>mid)        return getsum(x,y,2*n+1);    else    {        return getsum(x,mid,2*n)+getsum(mid+1,y,2*n+1);    }}void update(int x , int y , int n){    int mid=(tree[n].l+tree[n].r)>>1;    if(tree[n].l==x&&tree[n].r==y)    {        tree[n].sum-=(y-x+1);        tree[n].cha++;        return ;    }    if(y<=mid)        update(x,y,2*n);    else if(x>mid)        update(x,y,2*n+1);    else    {        update(x,mid,2*n);        update(mid+1,y,2*n+1);    }    tree[n].sum=tree[2*n].sum+tree[2*n+1].sum;}int main(){    int n,m,q;    while(cin>>n>>m>>q)    {        for(int i=1;i<=n;i++)            scanf("%d",&a[i]);        buildtree(1,n,1);        while(q--)        {            int zhi;            scanf("%d",&zhi);            printf("%d\n",getsum(zhi,zhi+m-1,1));            update(zhi,zhi+m-1,1);        }    }    return 0;}


0 0
原创粉丝点击