題目大意:
一個序列區間的反轉操作
還有就是把[a,b] 這段序列拿出來,插到新序列的第C個的後面。
思路:
反轉就和hdu 1890 一樣的。
插入的話,先旋轉到要的位置,拿出子序列。
然後旋轉到C位置,插入子序列。
#include#include #include #include #define inf 0x3f3f3f3f #define maxn 333333 #define keyTree (ch[ch[root][1]][0]) using namespace std; typedef long long LL; int S[maxn],que[maxn],ch[maxn][2],pre[maxn],siz[maxn]; int root,top1,top2; int val[maxn],a[maxn]; int rev[maxn]; bool first; void New(int &x,int PRE,int v) { if(top2)x=S[--top2]; else x=++top1; ch[x][0]=ch[x][1]=0; siz[x]=1; pre[x]=PRE; /*special*/ rev[x]=0; val[x]=v; } void pushup(int x)/*special*/ { siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+1; } void pushdown(int x)/*special*/ { if(rev[x]) { rev[ch[x][0]]^=1; rev[ch[x][1]]^=1; swap(ch[x][0],ch[x][1]); rev[x]=0; } } void build(int &x,int s,int e,int f) { if(s>e)return; int mid=(s+e)>>1; New(x,f,mid); if(s mid)build(ch[x][1],mid+1,e,x); pushup(x); } void Rotate(int x,int kind) { int y=pre[x]; pushdown(x); pushdown(y); ch[y][!kind]=ch[x][kind]; pre[ch[x][kind]]=y; if(pre[y])ch[pre[y]][ch[pre[y]][1]==y]=x; pre[x]=pre[y]; ch[x][kind]=y; pre[y]=x; pushup(y); } void Splay(int x,int goal) { pushdown(x); while(pre[x]!=goal) { if(pre[pre[x]]==goal) Rotate(x,ch[pre[x]][0]==x); else { int y=pre[x]; int kind=ch[pre[y]][0]==y; if(ch[y][kind]==x){ Rotate(x,!kind); Rotate(x,kind); } else { Rotate(y,kind); Rotate(x,kind); } } } pushup(x); if(goal==0)root=x; } void RotateTo(int k,int goal) { int r=root; pushdown(r); while(siz[ch[r][0]]!=k) { if(k