<font size=3>Portal -- > bzoj 3678php
這題==真實智力康復qwqnode
然而衆多神犇都說是10min寫完的題我。。可能寫了近1h吧==深深感覺到本身的弱小qwqios
(丟上來是由於。。個人splay實在是太垃圾了==)ui
其實就是splay的裸題啊qwq~~(而後由於過於不熟練致使寫了巨久==)~~而後的話不一樣的地方就是插入的時候你不能一個一個往裏面插。。由於插入的是連續的一段數,咱們考慮直接將這段數存在一個點裏面,在須要用其中的某個位置的時候再把這個位置分離出來spa
具體實現的話就是每一個節點維護$vall$和$valr$就行了,提取某一個位置(假如說是第$x$個位置)的時候咱們先找到這個位置再哪一個點裏面,而後把這個點(若是有的話)分紅三個點,$x$以前的數一個點,$x$一個點,$x$以後的數一個點,而後返回一下就行了,注意一下splay中的父子關係什麼的code
刪除$[l,r]$位置中的數的話直接把$l-1$這個位置和$r+1$這個位置提取出來,而後大力splay:先把$l-1$轉到根,再把$r+1$轉到$l-1$的左兒子,這樣$r+1$的整個左子樹就是$[l,r]$了,那咱們直接把$r+1$的左兒子斷掉就行了get
代碼大概長這個樣子string
#include<iostream> #include<cstdio> #include<cstring> #define mp make_pair #define Pr pair<int,int> using namespace std; const int N=1e5+10,S=N*10; int n,m,ans; namespace Splay{/*{{{*/ int ch[S][2],vall[S],valr[S],fa[S],sz[S]; int n,tot,rt; int which(int x){return ch[fa[x]][1]==x;} bool isroot(int x){return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;} int newnode(int l,int r){ ch[++tot][0]=0; ch[tot][1]=0; vall[tot]=l; valr[tot]=r; sz[tot]=r-l+1; return tot; } void pushup(int x){sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+(valr[x]-vall[x]+1);} void rotate(int x){ int dir=which(x),f=fa[x]; if (!isroot(f)) ch[fa[f]][which(f)]=x; fa[x]=fa[f]; fa[f]=x; if (ch[x][dir^1]) fa[ch[x][dir^1]]=f; ch[f][dir]=ch[x][dir^1]; ch[x][dir^1]=f; pushup(f); pushup(x); } void splay(int x,int top){ for (int f=fa[x]; fa[x]!=top; f=fa[x]){ if (fa[f]!=top) rotate(which(f)==which(x)?f:x); rotate(x); } if (!top) rt=x; } int _build(int l,int r){ if (l>r) return 0; int mid=l+r>>1; if (l==r){sz[mid]=1; return mid;} ch[mid][0]=_build(l,mid-1); ch[mid][1]=_build(mid+1,r); if (ch[mid][0]) fa[ch[mid][0]]=mid; if (ch[mid][1]) fa[ch[mid][1]]=mid; pushup(mid); return mid; } void build(int l,int r){rt=_build(l,r); tot=r;} int get_pos(int x,int k){ if (k<=sz[ch[x][0]]) return get_pos(ch[x][0],k); if (k>sz[ch[x][0]]+(valr[x]-vall[x]+1)) return get_pos(ch[x][1],k-(sz[ch[x][0]]+valr[x]-vall[x]+1)); int nw; k-=sz[ch[x][0]]; if (k!=1){ nw=newnode(vall[x],vall[x]+k-2); vall[x]=valr[nw]+1; ch[nw][0]=ch[x][0]; fa[ch[x][0]]=nw; ch[x][0]=nw; fa[nw]=x; pushup(nw); k=1; } if (k!=valr[x]-vall[x]+1){ nw=newnode(vall[x]+k,valr[x]); valr[x]=vall[nw]-1; ch[nw][1]=ch[x][1]; fa[ch[x][1]]=nw; ch[x][1]=nw; fa[nw]=x; pushup(nw); } return x; } Pr split(int l,int r){ int le=get_pos(rt,l),ri=get_pos(rt,r); splay(le,0); splay(ri,le); return mp(le,ri); } void insert(int p,int l,int r){ Pr rec=split(p,p+1); int nw=newnode(l,r); ch[rec.second][0]=nw; fa[nw]=rec.second; pushup(rec.second); pushup(rec.first); } void del(int l,int r){ Pr rec=split(l-1,r+1); ch[rec.second][0]=0; pushup(rec.second); pushup(rec.first); } int query(int x){ int pos=get_pos(rt,x); return vall[pos]; } }/*}}}*/ int main(){ #ifndef ONLINE_JUDGE freopen("a.in","r",stdin); #endif int op,x,y,p; scanf("%d%d",&n,&m); for (int i=2;i<=n+1;++i){ scanf("%d",&x); Splay::vall[i]=Splay::valr[i]=x; } Splay::build(1,n+2);//0~n+1 for (int i=1;i<=m;++i){ scanf("%d",&op); if (op==0){ scanf("%d%d%d",&p,&x,&y); Splay::insert(p+1,x,y); } else if (op==1){ scanf("%d%d",&x,&y); Splay::del(x+1,y+1); } else{ scanf("%d",&p); printf("%d\n",Splay::query(p+1)); } } }