這道題確定夠坑的 太卡時間了 我只想說G++超時 C++剛剛過
每個節點記錄最大傷害 最小傷害 子節點應該增加的傷害 注意更新時停止的條件
#include#include #include using namespace std; #define LL(x) (x<<1) #define RR(x) ((x<<1)|1) struct node { int large,few,add; }num[4*200000]; int k,flash; int max(int a,int b) { return a>b?a:b; } int min(int a,int b) { return a<b?a:b; } int make(int L,int R,int mark) { int mid=(L+R)/2; num[mark].large=num[mark].few=num[mark].add=0; if(L==R) return 0; make(L,mid,LL(mark)); make(mid+1,R,RR(mark)); return 0; } int deal(int a) { num[LL(a)].few+=num[a].add; num[LL(a)].large+=num[a].add; num[RR(a)].large+=num[a].add; num[RR(a)].few+=num[a].add; num[LL(a)].add+=num[a].add; num[RR(a)].add+=num[a].add; num[a].add=0; return 0; } int update(int L,int R,int left,int right,int mark,int x) { int mid=(L+R)/2; if(L==left&&R==right) { if(num[mark].few>=k) { num[mark].few+=2*x; num[mark].large+=2*x; num[mark].add+=2*x; return 0; } else if(num[mark].large<k) { num[mark].few+=x; num[mark].large+=x; num[mark].add+=x; return 0; } deal(mark); update(L,mid,L,mid,LL(mark),x); update(mid+1,R,mid+1,R,RR(mark),x); num[mark].large=max(num[LL(mark)].large,num[RR(mark)].large); num[mark].few=min(num[LL(mark)].few,num[RR(mark)].few); return 0; } if(num[mark].add>0) { deal(mark); } if(right<=mid) { update(L,mid,left,right,LL(mark),x); } else if(left>mid) { update(mid+1,R,left,right,RR(mark),x); } else { update(L,mid,left,mid,LL(mark),x); update(mid+1,R,mid+1,right,RR(mark),x); } num[mark].large=max(num[LL(mark)].large,num[RR(mark)].large); num[mark].few=min(num[LL(mark)].few,num[RR(mark)].few); return 0; } int print(int L,int R,int mark) { int mid=(L+R)/2; if(L==R) { if(flash!=0) printf(" "); flash++; printf("%d",num[mark].large); return 0; } if(num[mark].add>0) { deal(mark); } print(L,mid,LL(mark)); print(mid+1,R,RR(mark)); return 0; } int main() { int i,j,n,m,a,b,c; while(~scanf("%d%d%d",&n,&m,&k)) { //memset(num,0,sizeof(num)); make(1,n,1); for(i=1;i<=m;i++) { scanf("%d%d%d",&a,&b,&c); update(1,n,a,b,1,c); } flash=0; print(1,n,1); printf("\n"); } return 0; }