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
635Submit 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);
}
}
}
相关文章推荐
- 根据两点经纬度计算距离和角度——java实现
- Matlab位运算笔记
- 运算符优先级
- iOS 页面传值方式 单例,block,代理协议方法,通知中心
- ORACLE体系结构
- Hibernate的原理体系架构,五大核心接口,Hibernate对象的三种状态转换,事务管理
- 20145208《Java程序设计》第2周学习总结
- 在Ubuntu14.04上搭建Bugzilla
- SVN更新错误:类加载失败,无法读取项目文件"web.csproj"
- [概率论 DP] BZOJ 3652 大新闻
- hdu5644 King's Pilots 【费用流】
- Faster RCNN 运行自己的数据,刚开始正常,后来就报错: Index exceeds matrix dimensions. Error in ori_demo (line 114) boxes_cell{i} = [boxes(:, (1+(i-1)*4):(i*4)), scores(:, i)];
- Java并发包中CountDownLatch的工作原理、使用示例
- Linux内核分析— —构造一个简单的Linux系统MenuOS(20135213林涵锦)
- 作业二
- [转]开发Visual Studio风格的用户界面--MagicLibrary使用指南
- (八)黑马程序员——反射
- C++ const型成员函数与 non-const型成员函数 (二)
- [Splay] NOI2005 维修数列
- 机房重构——报表