fzu2171(线段树成段更新)
2014-04-28 10:59
183 查看
地址:http://acm.fzu.edu.cn/problem.php?pid=2171
Problem 2171 防守阵地 II
Accept: 32 Submit: 116
部队中总共有N个士兵,每个士兵有各自的能力指数Xi,在一次演练中,指挥部确定了M个需要防守的地点,指挥部将选择M个士兵依次进入指定地点进行防守任务,获得的参考指数即为M个士兵的能力之和。随着时间的推移,指挥部将下达Q个指令来替换M个进行防守的士兵们,每个参加完防守任务的士兵由于疲惫等原因能力指数将下降1。现在士兵们排成一排,请你计算出每次进行防守的士兵的参考指数。
输入包含多组数据。
输入第一行有两个整数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。
输出Q行,每行一个整数,为每次指令执行之后进行防守的士兵参考指数。
5 3 32 1 3 1 4123
635
思路:首现用一般的成段更新代码写了下,提交后发现超时。于是改变下策略,在没一次查询中将变化记录下来,如果下一次需要向下查询时就将记录的变化赋予下一段,然后将变化后的值返回给上一段,这样就行了。
代码:
Problem 2171 防守阵地 II
Accept: 32 Submit: 116
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<vector> #include<queue> using namespace std; struct node{ int l,r,sum,pl; }tree[100001*4]; void build(int l,int r,int k){ tree[k].l=l; tree[k].r=r; tree[k].pl=0; if(l==r){ scanf("%d",&tree[k].sum); return ; } int m=(l+r)/2; build(l,m,k*2); build(m+1,r,k*2+1); tree[k].sum=tree[k*2].sum+tree[k*2+1].sum; } int getsum(int l,int r,int k){ if(l<=tree[k].l&&r>=tree[k].r){ tree[k].pl++; //记录变化 tree[k].sum-=(tree[k].r-tree[k].l+1); return tree[k].sum+tree[k].r-tree[k].l+1; } int m=(tree[k].l+tree[k].r)/2,ans; if(tree[k].pl){ tree[k*2].sum-=(tree[k].pl*(tree[k*2].r-tree[k*2].l+1)); //将变化赋予下一段 tree[k*2+1].sum-=(tree[k].pl*(tree[k*2+1].r-tree[k*2+1].l+1)); tree[k*2].pl+=tree[k].pl; //记录变化,需要注意这里是+= tree[k*2+1].pl+=tree[k].pl; tree[k].pl=0; } if(m>=r) ans=getsum(l,r,k*2); else if(m<l) ans=getsum(l,r,k*2+1); else ans=getsum(l,m,k*2)+getsum(m+1,r,k*2+1); tree[k].sum=tree[k*2].sum+tree[k*2+1].sum; //变化后的值注意返回 return ans; } int main(){ int n,m,q; while(scanf("%d%d%d",&n,&m,&q)>0){ build(1,n,1); while(q--){ scanf("%d",&n); printf("%d\n",getsum(n,n+m-1,1)); } } return 0; }
相关文章推荐
- fzu 2171 防守阵地 II(线段树,成段更新,查询一段区间和)
- FZU 2171 —— 防守阵地 II(线段树,区间求和+区间更新)
- 树状数组+ 成段更新+ 成段输出 裸题 Fzu 2171 防守阵地2
- FZU2171:防守阵地 II(线段树)
- fzu 2171 防守阵地 II(线段树 区间更新)
- FZU Problem 2171 防守阵地 II (线段树,区间更新)
- FZU2171 防守阵地 II(线段树)
- 【FZU】2171 防守阵地 II 线段树
- FZU2171 - 防守阵地 II 线段树的区间更新
- FZU1608(线段树成段更新,区间求和pushdown延迟标记结构体版)
- FZU 2171 线段树 区间更新求和
- fzu 2171 线段树 lazy标记
- FZU 2105Digits Count(线段树 + 成段更新)
- FZU2171 防守阵地 II (线段树)
- FZU Problem 2171 防守阵地 II (线段树模板题)
- FZU 2171 防守阵地 II(线段树区间更新【lazy标记】)
- FZU 2171(线段树的延迟标记)
- FZU Problem 2171 防守阵地 II (线段树区间更新模板题)
- FZU - 2105 Digits Count (线段树成段更新)
- fzu 2171 线段树区间更新