啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊
坑爹的缩点$p14y
我已经出离愤怒了,样例能不能给个坑多点的?!
不管怎么改样例测出来都是对的TAT
然而狂TLE。
果然还是要静态查错(⊙o⊙)
于是我运用脑髓,放出眼光,终于发现,艹,一个地方写错了导致多了好多结点。
好坑啊。
不过还是过了2333333333,224MS感觉还好。
#include<iostream> #include<cstdio> #include<cstring> #include<queue> using namespace std; const int N=200000+5; int l[N],r[N],sz[N],ch[N][2],fa[N],root,id[N],a[N],cnt; queue<int>q; inline void pushup(int x){sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+r[x]-l[x]+1;} inline void rotate(int x,int &k){ int y=fa[x],z=fa[y],l=(ch[y][1]==x),r=l^1; if(k==y)k=x; else ch[z][ch[z][1]==y]=x; fa[x]=z;fa[y]=x;fa[ch[x][r]]=y; ch[y][l]=ch[x][r];ch[x][r]=y; pushup(y);pushup(x); } inline void splay(int x,int &k){ while(x!=k){ int y=fa[x],z=fa[y]; if(y!=k){ if(ch[y][0]==x^ch[z][0]==y)rotate(x,k); else rotate(y,k); } rotate(x,k); } } inline void pushdown(int x,int k){ if(l[x]==r[x])return; int tmp; if(k>1){ if(!q.empty())tmp=q.front(),q.pop();else tmp=++cnt; if(ch[x][0])ch[tmp][0]=ch[x][0],fa[ch[x][0]]=tmp;ch[x][0]=tmp;fa[tmp]=x; l[tmp]=l[x];r[tmp]=l[x]+k-2;pushup(tmp); } if(k<r[x]-l[x]+1){ if(!q.empty())tmp=q.front(),q.pop();else tmp=++cnt; if(ch[x][1])ch[tmp][1]=ch[x][1],fa[ch[x][1]]=tmp;ch[x][1]=tmp;fa[tmp]=x; r[tmp]=r[x];l[tmp]=l[x]+k;pushup(tmp); } l[x]=r[x]=l[x]+k-1; pushup(x); } int kth(int x,int k){ if(k<=sz[ch[x][0]])return kth(ch[x][0],k); k-=sz[ch[x][0]]; if(k>r[x]-l[x]+1)return kth(ch[x][1],k-(r[x]-l[x]+1)); pushdown(x,k); return x; } int select(int x,int k){ if(k<=sz[ch[x][0]])return select(ch[x][0],k); k-=sz[ch[x][0]]; if(k>r[x]-l[x]+1)return select(ch[x][1],k-(r[x]-l[x]+1)); return l[x]+k-1; } int split(int a,int b){ int x=kth(root,a),y=kth(root,b); splay(x,root);splay(y,ch[x][1]); return y; } void rec(int x){ if(!x)return; rec(ch[x][0]);rec(ch[x][1]);q.push(x); ch[x][0]=ch[x][1]=fa[x]=0; } void del(int a,int b){ int y=split(a,b+2),x=ch[y][0]; rec(x);ch[y][0]=0; pushup(y);pushup(fa[y]); } void ins(int p,int a,int b){ int x=split(p+1,p+2); int tmp;if(!q.empty())tmp=q.front(),q.pop();else tmp=++cnt; ch[x][0]=tmp;fa[tmp]=x;l[tmp]=a;r[tmp]=b;pushup(tmp);pushup(x);pushup(fa[x]); } void build(int x,int y,int f){ if(x>y)return; int mid=x+y>>1,now=id[mid],last=id[f]; if(x==y){ sz[now]=1; }else build(x,mid-1,mid),build(mid+1,y,mid); fa[now]=last;l[now]=r[now]=a[mid];pushup(now); ch[last][mid>=f]=now; } int main(){ int n,m;scanf("%d%d",&n,&m); for(int i=1;i<=n;i++)scanf("%d",&a[i+1]); for(int i=1;i<=n+2;i++)id[i]=i; build(1,n+2,0);root=n+3>>1;cnt=n+2; int sym,p,a,b; while(m--){ scanf("%d",&sym); switch(sym){ case 0:scanf("%d%d%d",&p,&a,&b);ins(p,a,b);break; case 1:scanf("%d%d",&a,&b);del(a,b);break; case 2:scanf("%d",&p);printf("%d\n",select(root,p+1));break; } } return 0; }