//HDOJ 4107 Gangster 線段樹 成段更新變化
/*
題意:n個數,初始都是0,m次更新操作:
若元素a[i] < p,則a[i]+=c,否則a[i]+=2*c
最後輸出所有的數字
思路:當一個區間內的最大值mmax<p,則該區間內所有的數都+c,樸素的成段更新
當一個區間內的最小是mmax>=p,則該區間內的所有的數都+2*才,樸素的成段更新
不滿足的話往下一直更新,滿足的話lazy後返回
*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define N 200005
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
#define Max(a,b) (a>b?a:b)
#define Min(a,b) (a<b?a:b)
int mmax[N<<2],mmin[N<<2],add[N<<2];
int n,m,p;
void Pushup(int rt){
mmax[rt] = Max(mmax[rt<<1],mmax[rt<<1|1]);
mmin[rt] = Min(mmin[rt<<1],mmin[rt<<1|1]);
}
void Pushdown(int rt){
if(add[rt]){
add[rt<<1] += add[rt];
add[rt<<1|1] += add[rt];
mmax[rt<<1] += add[rt];
mmax[rt<<1|1] += add[rt];
mmin[rt<<1] += add[rt];
mmin[rt<<1|1] +=add[rt];
add[rt] = 0;
}
}
void Build(){
memset(mmax,0,sizeof(mmax));
memset(mmin,0,sizeof(mmin));
memset(add,0,sizeof(add));
}
void Update(int rt,int l,int r,int L,int R,int c){
if(L <= l && R >= r){
if(mmax[rt] < p){
add[rt] += c;
mmax[rt] += c;
mmin[rt] += c;
return;
}
if(mmin[rt] >= p){
add[rt] += 2*c;
mmax[rt] += 2*c;
mmin[rt] += 2*c;
return;
}
}
Pushdown(rt);
int mid = (l + r) >> 1;
if(L <= mid) Update(lson,L,R,c);
if(R > mid ) Update(rson,L,R,c);
Pushup(rt);
}
void Print(int rt,int l,int r){
if(l == r){
if(l == 1) printf("%d",mmax[rt]);
else printf(" %d",mmax[rt]);
return ;
}
Pushdown(rt);
int mid =(l + r) >> 1;
Print(lson);
Print(rson);
}
inline void scan_d(int &ret) {
char c; ret=0;
while((c=getchar())<'0'||c>'9');
while(c>='0'&&c<='9') ret=ret*10+(c-'0'),c=getchar();
}
int main(){
int a,b,c;
while(scanf("%d %d %d",&n,&m,&p)!=EOF){
Build();
while(m--){
scan_d(a);
scan_d(b);
scan_d(c);
Update(1,1,n,a,b,c);
}
Print(1,1,n);
puts("");
}
return 0;
}
HDOJ 4107 Gangster 線段樹 成段更新變化
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.