维护每个区间的最小值和最大值,update的时候判断low[rt]与up[rt]和p的大小关系,进行更新操作。
卡时卡得很紧。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 using 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; }