LOJ#106. 二逼平衡树 树套树
这里写的是线段树套权值线段树和 set.
写代码的时间大概是 40 min,然后调试时间是 10 分钟左右,感觉这种数据结构题写的时候仔细检查的话还是比较好调的.
code:
#include <bits/stdc++.h> #define ll long long #define N 50009 #define lson s[x].ls #define rson s[x].rs #define inf 100000000 #define INF 2147483647 #define setIO(s) freopen(s".in","r",stdin) using namespace std; set<int>se[N<<2]; set<int>::iterator it; int n,m,tot,rt[N<<2],a[N]; struct data { int ls,rs,sum; }s[N*400]; int Getpr(int x,int v) { it=se[x].lower_bound(v); if(it==se[x].begin()) return -INF; it--;return *it; } int Getaf(int x,int v) { it=se[x].lower_bound(v); if(it==se[x].end()) return INF; if((*it)>v) return *it; it++; if(it==se[x].end()) return INF; return *it; } int update(int &x,int l,int r,int p,int v) { if(!x) x=++tot; s[x].sum+=v; if(l==r) return s[x].sum; int mid=(l+r)>>1; if(p<=mid) return update(lson,l,mid,p,v); else return update(rson,mid+1,r,p,v); } int query(int x,int l,int r,int v) { if(!x) return 0; int mid=(l+r)>>1; if(v>mid) return s[lson].sum+query(rson,mid+1,r,v); else return query(lson,l,mid,v); } void Modify(int l,int r,int now,int p,int v,int op) { int flag=update(rt[now],-inf,inf,v,op); if(op==1) se[now].insert(v); if(op==-1&&!flag) se[now].erase(v); if(l==r) return; int mid=(l+r)>>1; if(p<=mid) Modify(l,mid,now<<1,p,v,op); else Modify(mid+1,r,now<<1|1,p,v,op); } int Ask_rank(int l,int r,int now,int L,int R,int k) { if(l>=L&&r<=R) return query(rt[now],-inf,inf,k); int mid=(l+r)>>1,re=0; if(L<=mid) re+=Ask_rank(l,mid,now<<1,L,R,k); if(R>mid) re+=Ask_rank(mid+1,r,now<<1|1,L,R,k); return re; } int Ask_pr(int l,int r,int now,int L,int R,int k) { if(l>=L&&r<=R) return Getpr(now,k); int mid=(l+r)>>1,re=-INF; if(L<=mid) re=max(re,Ask_pr(l,mid,now<<1,L,R,k)); if(R>mid) re=max(re,Ask_pr(mid+1,r,now<<1|1,L,R,k)); return re; } int Ask_af(int l,int r,int now,int L,int R,int k) { if(l>=L&&r<=R) return Getaf(now,k); int mid=(l+r)>>1,re=INF; if(L<=mid) re=min(re,Ask_af(l,mid,now<<1,L,R,k)); if(R>mid) re=min(re,Ask_af(mid+1,r,now<<1|1,L,R,k)); return re; } int Ask_IS(int l,int r,int now,int L,int R,int k) { if(l>=L&&r<=R) return *se[now].lower_bound(k)==k; int mid=(l+r)>>1,re=0; if(L<=mid) re|=Ask_IS(l,mid,now<<1,L,R,k); if(R>mid) re|=Ask_IS(mid+1,r,now<<1|1,L,R,k); return re; } char *p1,*p2,buf[100000]; #define nc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++) int rd() { int x=0,flag=1; char c; while(c<48) { c=nc(); if(c=='-') flag=-1; } while(c>47) { x=(((x<<2)+x)<<1)+(c^48),c=nc(); } return x*flag; } int main() { // setIO("input"); int x,y,z,l,r,k,L,R,mid,ans; n=rd(),m=rd(); for(int i=1;i<=n;++i) x=rd(),Modify(1,n,1,i,x,1),a[i]=x; for(int i=1;i<=m;++i) { z=rd(); if(z==1) { l=rd(),r=rd(),k=rd(); printf("%d\n",Ask_rank(1,n,1,l,r,k)+1); } if(z==2) { l=rd(),r=rd(),k=rd(),--k; ans=L=-inf,R=inf; while(L<=R) { mid=(L+R)>>1; if(Ask_rank(1,n,1,l,r,mid)>=k) ans=mid,R=mid-1; else L=mid+1; } if(Ask_IS(1,n,1,l,r,ans)) { printf("%d\n",ans); continue; } int X=Ask_pr(1,n,1,l,r,ans); int Y=Ask_af(1,n,1,l,r,ans); if(Y!=INF) { if(Ask_rank(1,n,1,l,r,Y)==k) { printf("%d\n",Y); continue; } } printf("%d\n",X); } if(z==3) { x=rd(),y=rd(); Modify(1,n,1,x,a[x],-1); Modify(1,n,1,x,y,1); a[x]=y; } if(z==4) { l=rd(),r=rd(),k=rd(); printf("%d\n",Ask_pr(1,n,1,l,r,k)); } if(z==5) { l=rd(),r=rd(),k=rd(); printf("%d\n",Ask_af(1,n,1,l,r,k)); } } return 0; }