题目链接:
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;
}