题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=4107
题目大意:
有n个数,m个操作,给一个p,每个操作a,b,c,作用于a~b区间的数,如果该数大于等于p,则该树+2*c,否则+c.求所有操作完成后,数组中的数。
解题思路:
线段树区间更新,lazy标记。
线段树维护一个区间的最大值Max,区间的最小值MIn。以及整个区间增加的值。当Max<p或Min>=p时,直接更新当前区间的add,Max,MIn.否则更新到叶子。
每次更新时,先下传,然后上传更新。
代码:
#include<iostream> #include<cmath> #include<cstdio> #include<sstream> #include<cstdlib> #include<string> #include<cstring> #include<algorithm> #include<vector> #include<map> #include<set> #include<stack> #include<list> #include<queue> #include<ctime> #include<bitset> #define eps 1e-6 #define INF 0x3f3f3f3f #define PI acos(-1.0) #define ll __int64 #define LL long long #define lson l,m,(rt<<1) #define rson m+1,r,(rt<<1)|1 #pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; #define Maxn 210000 int p; struct Node { int Min,Max,add; }node[Maxn<<2]; void pushup(int rt) //向上更新 { node[rt].Min=min(node[rt<<1].Min,node[rt<<1|1].Min); node[rt].Max=max(node[rt<<1].Max,node[rt<<1|1].Max); } void pushdown(int rt) { if(node[rt].add) //往下更新 { node[rt<<1].add+=node[rt].add; node[rt<<1].Max+=node[rt].add; node[rt<<1].Min+=node[rt].add; node[rt<<1|1].add+=node[rt].add; node[rt<<1|1].Max+=node[rt].add; node[rt<<1|1].Min+=node[rt].add; node[rt].add=0; } } void build(int l,int r,int rt) { node[rt].Min=node[rt].Max=node[rt].add=0; if(l==r) return ; int m=(l+r)>>1; build(lson); build(rson); } void update(int l,int r,int rt,int a,int b,int c) { // printf("%d\n",rt); // system("pause"); if(a<=l&&b>=r) // { if(node[rt].Min>=p) //对整个区间更新 { node[rt].add+=2*c; node[rt].Max+=2*c; node[rt].Min+=2*c; return ; } if(node[rt].Max<p) //对整个区间更新 { node[rt].add+=c; node[rt].Max+=c; node[rt].Min+=c; return ; } } pushdown(rt); //下传后马上要上传更新 int m=(l+r)>>1; if(a<=m) update(lson,a,b,c); if(b>m) update(rson,a,b,c); pushup(rt); } void query(int l,int r,int rt) { if(l==r) //从左至右依次输出 { if(l!=1) printf(" %d",node[rt].add); else printf("%d",node[rt].add); return ; } int m=(l+r)>>1; pushdown(rt); query(lson); query(rson); } int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); int n,m; while(~scanf("%d%d%d",&n,&m,&p)) { build(1,n,1); for(int i=1;i<=m;i++) { int a,b,c; scanf("%d%d%d",&a,&b,&c); update(1,n,1,a,b,c); } query(1,n,1); putchar('\n'); } return 0; }