码迷,mamicode.com
首页 > 其他好文 > 详细

FZU Problem 2171 防守阵地 II (裸线段树 懒惰标记)

时间:2015-05-17 09:23:19      阅读:134      评论:0      收藏:0      [点我收藏+]

标签:problem 2171 防守阵地 ii   线段树   懒惰标记   

 Problem 2171 防守阵地 II

Accept: 259    Submit: 987
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<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>

#define lson idx<<1,l,mid
#define rson idx<<1|1,mid+1,r
#define lc   idx<<1
#define rc   idx<<1|1
#define N    100010

using namespace std;

int n,m,q;
int sum[N<<2],st[N<<2];

void push_up(int idx) {
    sum[idx]=sum[lc]+sum[rc];
}

void build(int idx,int l,int r) {
    st[idx]=0;
    if(l==r) {
        scanf("%d",&sum[idx]);
        return;
    }
    int mid=(l+r)>>1;
    build(lson);
    build(rson);
    push_up(idx);
}

void push_down(int idx,int d) {
    if(st[idx]<0) {
        st[lc]+=st[idx];
        st[rc]+=st[idx];
        sum[lc]+=(d-d/2)*st[idx];
        sum[rc]+=d/2*st[idx];
    }
    st[idx]=0;
}

void update(int idx,int l,int r,int x,int y,int k) {
    if(x<=l&&y>=r) {
        sum[idx]+=(r-l+1)*k;
        st[idx]+=k;
        return;
    }
    push_down(idx,r-l+1);
    int mid=(l+r)>>1;
    if(x<=mid)update(lson,x,y,k);
    if(y>mid)update(rson,x,y,k);
    push_up(idx);
}

int query(int idx,int l,int r,int x,int y) {
    if(x<=l&&y>=r)return sum[idx];
    push_down(idx,r-l+1);
    int mid=(l+r)>>1;
    int res=0;
    if(x<=mid)res+=query(lson,x,y);
    if(y>mid)res+=query(rson,x,y);
    return res;
}

int main() {
    //freopen("in.txt","r",stdin);
    while(~scanf("%d%d%d",&n,&m,&q)) {
        build(1,1,n);
        int s,e;
        while(q--) {
            scanf("%d",&s);
            e=s+m-1;
            printf("%d\n",query(1,1,n,s,e));
            update(1,1,n,s,e,-1);
        }
    }
    return 0;
}


FZU Problem 2171 防守阵地 II (裸线段树 懒惰标记)

标签:problem 2171 防守阵地 ii   线段树   懒惰标记   

原文地址:http://blog.csdn.net/acm_baihuzi/article/details/45775749

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!