Maintain the minimum and maximum values of each interval, and determine the relationship between low [RT] And up [RT] and P during update to perform the update operation.
The card is very tight.
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1using namespace std;const int maxn=211111;int up[maxn<<2],low[maxn<<2],col[maxn<<2];int n,m,p;inline int max(int &a,int &b){ if(a>b)return a; return b;}inline int min(int &a,int &b){ if(a<b)return a; return b;}void build(int l,int r,int rt){// up[rt]=low[rt]=col[rt]=0; if(l==r)return ; int m=(l+r)>>1; build(lson); build(rson);}void pushup(int rt){ up[rt]=max(up[rt<<1],up[rt<<1|1]); low[rt]=min(low[rt<<1],low[rt<<1|1]);}void down(int rt){ if(col[rt]){ col[rt<<1]+=col[rt]; col[rt<<1|1]+=col[rt]; up[rt<<1]+=col[rt]; up[rt<<1|1]+=col[rt]; low[rt<<1]+=col[rt]; low[rt<<1|1]+=col[rt]; col[rt]=0; }}void update(int L,int R,int c,int l,int r,int rt){ if(L<=l&&R>=r){ if(up[rt]<p)up[rt]+=c,low[rt]+=c,col[rt]+=c; else if(low[rt]>=p)low[rt]+=2*c,up[rt]+=2*c,col[rt]+=2*c; else { down(rt); int m=(l+r)>>1; if(L<=m)update(L,R,c,lson); if(R>m)update(L,R,c,rson); pushup(rt); } return; } down(rt); int m=(l+r)>>1; if(L<=m)update(L,R,c,lson); if(R>m)update(L,R,c,rson); pushup(rt);}void query(int l,int r,int rt){ if(l==r){ if(l!=1)printf(" "); printf("%d",low[rt]); return ; } down(rt); int m=(l+r)>>1; query(lson); query(rson);}void run(){ memset(up,0,sizeof(int)*((n<<2)+10)); memset(low,0,sizeof(int)*((n<<2)+10)); memset(col,0,sizeof(int)*((n<<2)+10)); build(1,n,1); while(m--){ int a,b,c; scanf("%d%d%d",&a,&b,&c); update(a,b,c,1,n,1); } query(1,n,1); puts("");}int main(){// freopen("in","r",stdin); while(scanf("%d%d%d",&n,&m,&p)>0)run(); return 0;}
HDU 4107 gangster line segment tree (segment update)