您的位置:首页 > 其它

FOJ 2171 防守阵地 II【线段树+区间更新】

2016-03-13 19:14 357 查看

 Problem 2171 防守阵地 II

Accept: 323    Submit: 1235

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

Submit  Back  Status  Discuss

大家不用质疑,这的确是个水题,我一开始害怕没敢敲,害怕什么呢?可能不为负值,如果出现负值要改为0的话,那可是个大工程。。。。。亲们不必要担心,样例中这样输入:

5 3 4

2 1 3 5 4

1

1

1

1

的输出是 6 3 0 -3.这样就可以AC了,所以直接敲,不要慌,wa了更不要慌,开大数组~~~另外不要考虑点更新的问题,m如果大的话是一定会T的~,然而为了测试,我也确实交了一发点更新,确实会T。

AC代码:
#include<stdio.h>
#include<string.h>
using namespace std;
#define lson l,m,rt*2
#define rson m+1,r,rt*2+1
int tree[2000000];
int flag[2000000];
void pushdown(int l,int r,int rt)//向下维护树内数据
{
if(flag[rt])//如果贪婪标记不是0(说明需要向下进行覆盖区间(或点)的值)
{
int m=(l+r)/2;
flag[rt*2]+=flag[rt];
flag[rt*2+1]+=flag[rt];
tree[rt*2]+=(m-l+1)*flag[rt];//千万理解如何覆盖的区间值(对应线段树的图片理解(m-l)+1)是什么意识.
tree[rt*2+1]+=(r-(m+1)+1)*flag[rt];
flag[rt]=0;
}
}
void pushup(int rt)
{
tree[rt]=tree[rt<<1]+tree[rt<<1|1];
}
void build( int l ,int r , int rt )
{
if( l == r )
{
scanf("%d",&tree[rt]);
flag[rt]=0;
return ;
}
else
{
int m = (l+r)>>1 ;
build(lson) ;
build(rson) ;
pushup(rt) ;
}
}
void update(int L,int R,int c,int l,int r,int rt)
{
if(L<=l&&r<=R)//覆盖的是区间~
{
tree[rt]+=c*((r-l)+1);//覆盖当前点的值
flag[rt]+=c;//同时懒惰标记~!
return ;
}
else
{
pushdown(l,r,rt);
int m=(l+r)/2;
if(L<=m)
{
update(L,R,c,lson);
}
if(m<R)
{
update(L,R,c,rson);
}
pushup(rt);
}
}
int Query(int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R)
{
return tree[rt];
}
pushdown(l,r,rt);
int m=(l+r)>>1;
int ans=0;
if(L<=m)
{
ans+=Query(L,R,lson);
}
if(m<R)
{
ans+=Query(L,R,rson);
}
return ans;
}
int main()
{
int n,m,q;
while(~scanf("%d%d%d",&n,&m,&q))
{
memset(flag,0,sizeof(flag));
build(1,n,1);
while(q--)
{
int x;
scanf("%d",&x);
printf("%d\n",Query(x,x+m-1,1,n,1));
update(x,x+m-1,-1,1,n,1);
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  FOJ 2171 FZU 2171