FZU 2171 防守阵地 II
题目链接:FZU 2171
分析:
每次计算X到X+M-1的和,然后X到X+M-1的值都减1。
#include <iostream>
#include <cstdio>
#include <string>
#include <algorithm>
#include <cmath>
using namespace std;
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
const int maxn = 100010;
int k, tn, tcase = 0;
int sum[maxn << 2],cnt[maxn << 2];
void pushup(int rt)
{
sum[rt] = sum[rt << 1]+sum[rt << 1 | 1];
}
void pushdown(int rt,int m)
{
if(cnt[rt])
{
cnt[rt<<1]+=cnt[rt];
cnt[rt<<1|1]+=cnt[rt];
sum[rt<<1]+=cnt[rt]*(m-(m>>1));
sum[rt<<1|1]+=cnt[rt]*(m>>1);
cnt[rt]=0;
}
}
void build(int l, int r, int rt)
{
cnt[rt]=0;
if (l == r)
{
scanf("%d",&sum[rt]);
return ;
}
int mid = (l + r) >> 1;
build(lson);
build(rson);
pushup(rt);
}
void update(int c,int L, int R,int l, int r, int rt)
{
if (L <= l && R>= r) // L<=l<=r<=R
{
cnt[rt]+=c;
sum[rt] += c*(r-l+1);
return ;
}
pushdown(rt,r-l+1);
int mid = (l + r) >> 1;
if (L <= mid)
update(c,L, R, lson);
if (R > mid)
update(c,L, R, rson);
pushup(rt);
}
int query(int L, int R, int l, int r, int rt,int lnc)
{
if (L <= l && R>= r) // L<=l<=r<=R
{
return sum[rt];
}
pushdown(rt,r-l+1);
int mid = (l + r) >> 1;
int ret = 0;
if (L <= mid)
ret +=query(L, R, lson,lnc+cnt[rt << 1]);
if (R > mid)
ret +=query(L, R, rson,lnc+cnt[rt << 1 | 1]);
return ret;
}
int main()
{
// freopen("in.txt","r",stdin);
int n,m,r,c;
while(scanf("%d %d %d", &n,&m,&r)!=EOF&&n)
{
build(1, n, 1);
for(int i=0;i<r;i++)
{
scanf("%d",&c);
// 查询c到c-m+1的和
printf("%d\n",query(c,c+m-1,1,n,1,0));
// c到c-m+1区域都减1
update(-1,c,c+m-1,1,n,1);
}
}
return 0;
}