1. 程式人生 > >BZOJ4592 [Shoi2015]腦洞治療儀(洛谷P4344)

BZOJ4592 [Shoi2015]腦洞治療儀(洛谷P4344)

BZOJ4592: [Shoi2015]腦洞治療儀(洛谷P4344)

線段樹

昨天一個字母打錯一晚上沒調出來。。。

挺裸的線段樹。

0直接做。1記錄下l0r0的1的個數後可以二分確定修補的右端點,也可以直接往下做到沒有為止,前者log2,後者比log稍微大一點。2對每個節點記一下最左邊、最右邊、最大的腦洞的長度,查詢的時候直接合並就好了,稍微有點細節。

程式碼:

#include<cctype>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 200005
#define F inline using namespace std; struct tree{ int mx,s,lx,rx,l,r,f; }t[N<<2]; int n,m,k,s; F char readc(){ static char buf[100000],*l=buf,*r=buf; if (l==r) r=(l=buf)+fread(buf,1,100000,stdin); return l==r?EOF:*l++; } F int _read(){ int x=0; char ch=readc(); while (!isdigit(ch)) ch=readc();
while (isdigit(ch)) x=(x<<3)+(x<<1)+(ch^48),ch=readc(); return x; } F void writec(int x){ if (x>9) writec(x/10); putchar(x%10+48); } F void _write(int x){ writec(x),puts(""); } void build(int x,int l,int r){ t[x].l=l,t[x].r=r,t[x].f=-1; if (l==r) return; int mid=l+r>>1;
build(x<<1,l,mid),build(x<<1|1,mid+1,r); } #define max(x,y) ((x)>(y)?(x):(y)) #define min(x,y) ((x)<(y)?(x):(y)) F void pshp(int x){ int l=x<<1,r=x<<1|1; t[x].s=t[l].s+t[r].s; t[x].mx=max(max(t[l].mx,t[r].mx),t[l].rx+t[r].lx); t[x].lx=t[l].lx,t[x].rx=t[r].rx; if (t[l].mx==t[l].r-t[l].l+1) t[x].lx+=t[r].lx; if (t[r].mx==t[r].r-t[r].l+1) t[x].rx+=t[l].rx; } F void pshd(int x){ int w=t[x].f,l=x<<1,r=x<<1|1; t[x].f=-1,t[l].f=t[r].f=w; t[l].lx=t[l].rx=t[l].mx=t[l].s=(w^1)*(t[l].r-t[l].l+1); t[r].lx=t[r].rx=t[r].mx=t[r].s=(w^1)*(t[r].r-t[r].l+1); } void mdfy(int x,int l,int r){ if (t[x].l>r||t[x].r<l) return; if (t[x].l>=l&&t[x].r<=r){ t[x].lx=t[x].rx=t[x].mx=t[x].s=t[x].r-t[x].l+1; t[x].f=0; return; } if (~t[x].f) pshd(x); mdfy(x<<1,l,r),mdfy(x<<1|1,l,r),pshp(x); } tree srch(int x,int l,int r){ tree xs={0,0,0,0},ls,rs; if (t[x].l>r||t[x].r<l) return xs; if (t[x].l>=l&&t[x].r<=r) return t[x]; if (~t[x].f) pshd(x); ls=srch(x<<1,l,r),rs=srch(x<<1|1,l,r); xs.mx=max(max(ls.mx,rs.mx),ls.rx+rs.lx); xs.lx=ls.lx,xs.rx=rs.rx; if (ls.lx==min(r,t[x<<1].r)-max(l,t[x<<1].l)+1) xs.lx+=rs.lx; if (rs.rx==min(r,t[x<<1|1].r)-max(l,t[x<<1|1].l)+1) xs.rx+=ls.rx; xs.s=ls.s+rs.s; return xs; } void chng(int x,int l,int r){ if (t[x].l>r||t[x].r<l||s==0) return; if (t[x].l>=l&&t[x].r<=r) if (s>=t[x].s){ s-=t[x].s,t[x].f=1; t[x].lx=t[x].rx=t[x].mx=t[x].s=0; return; } if (~t[x].f) pshd(x); chng(x<<1,l,r),chng(x<<1|1,l,r),pshp(x); } int main(){ for (n=_read(),m=_read(),build(1,1,n);m;m--){ int f=_read(),l=_read(),r=_read(),L,R; if (f==0) mdfy(1,l,r); else if (f==1){ L=_read(),R=_read(),s=r-l+1-srch(1,l,r).s; mdfy(1,l,r),chng(1,L,R); } else _write(srch(1,l,r).mx); } return 0; }