神犇救命,5分调试一周了

P4344 [SHOI2015] 脑洞治疗仪

```cpp #include<iostream> #include<cstdio> #include<algorithm> #include<cmath> #include<cstring> #define int long long #define N 200086 #define ls(x) (x<<1) #define rs(x) ((x<<1)+1) using namespace std; struct node { int val,ans,pre,bac,tag,len; }tree[N*4]; int n,m; void build(int pl,int l,int r) { tree[pl].len=r-l+1; if(l==r) { tree[pl].val=1; return ; } int lson=ls(pl),rson=rs(pl),mid=(l+r)>>1; build(lson,l,mid),build(rson,mid+1,r); tree[pl].val=tree[lson].val+tree[rson].val; return ; } void fix2(int pl) { tree[pl].pre=tree[pl].len; tree[pl].bac=tree[pl].len; tree[pl].ans=tree[pl].len; tree[pl].tag=2; tree[pl].val=0; } void fix1(int pl) { tree[pl].pre=0; tree[pl].bac=0; tree[pl].ans=0; tree[pl].tag=1; tree[pl].val=tree[pl].len; } void push_up(int pl) { int lson=ls(pl),rson=rs(pl); if(tree[lson].val==0) { tree[pl].pre=tree[lson].len+tree[rson].pre; } else { tree[pl].pre=tree[lson].pre; } if(tree[rson].val==0) { tree[pl].bac=tree[rson].len+tree[lson].bac; } else { tree[pl].bac=tree[rson].bac; } tree[pl].val=tree[lson].val+tree[rson].val; tree[pl].ans=max(tree[lson].ans,tree[rson].ans); tree[pl].ans=max(tree[pl].ans,tree[lson].bac+tree[rson].pre); return ; } void push_down(int pl) { if(tree[pl].tag==0) { return ; } int lson=ls(pl),rson=rs(pl); if(tree[pl].tag==2) { fix2(lson); fix2(rson); } else { fix1(lson); fix1(rson); } tree[pl].tag=0; //标记下传后应清空原标记 } int fill(int p,int l,int r,int pl,int pr,int val) { if(l>pr||r<pl||val==0) { return val; } int mid=(l+r)>>1,lson=ls(p),rson=rs(p),num=tree[p].len-tree[p].val; if(r<=pr&&l>=pl) { //填充写法有些问题 if(val>=num){ fix1(p); return val-num; } //您之前写的思路没有问题 分类处理有点错误 //但是您的写法麻烦而且容易出现错误 } push_down(p); int left=fill(rson,mid+1,r,pl,pr,fill(lson,l,mid,pl,pr,val)); push_up(p); return left; } int dig(int p,int l,int r,int pl,int pr) { if(r<pl||l>pr) { return 0; } if(r<=pr&&l>=pl) { int num=tree[p].val; fix2(p); return num; } int mid=(l+r)>>1,lson=ls(p),rson=rs(p); push_down(p); int num=dig(lson,l,mid,pl,pr)+dig(rson,mid+1,r,pl,pr); push_up(p); return num; } void work(int l,int r,int pl,int pr) { int val=dig(1,1,n,l,r); fill(1,1,n,pl,pr,val); return; } int find(int p,int l,int r,int pl,int pr) { if(l>pr||r<pl) { return 0; } if(r<=pr&&l>=pl) { return tree[p].ans; } push_down(p); int mid=(l+r)>>1,lson=ls(p),rson=rs(p); //答案统计有点问题 int an=min(tree[lson].bac,mid-pl+1)+min(tree[rson].pre,pr-mid); //答案越过分治中点 int an_=max(find(lson,l,mid,pl,pr),find(rson,mid+1,r,pl,pr)); //答案没有越过分治中点(未变) return max(an,an_); } signed main() { cin.tie(0),cout.tie(0); ios::sync_with_stdio(false); cin>>n>>m; build(1,1,n); for(int i=1; i<=m; ++i) { int ope; cin>>ope; if(ope==0) { int l,r; cin>>l>>r; dig(1,1,n,l,r); } else if(ope==1) { int l,r,l_,r_; cin>>l>>r>>l_>>r_; work(l,r,l_,r_); } else { int l,r; cin>>l>>r; cout<<find(1,1,n,l,r)<<endl; } } return 0; } ``` @[bobzbh](/user/111349) 给您修改了一下过了,改的地方都注释了
by Killer_joke @ 2022-12-29 11:48:17


感谢@Killer_joke的帮助,现在彻底明白啦
by bobzbh @ 2022-12-29 11:56:14


|