HDOJ 4107 Gangster 線段樹 成段更新變化

//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;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章