題目大意:
機器人可以每次反轉一個區間,要把當前最小的放在最前面。問他反轉前,那個數在第幾號位置。
思路:
可以知道Splay的左子樹就是在他左邊的數的個數,所以我們直接用他們的初始位置建樹。
然後用num排序。這時可以用從小到大的順序取出他們在數組中的位置。
把目標放在根節點。
然後找他的左子樹的個數+i,然後刪除根節點。
之前遇到一個思維上的問題,也是lcm提出來的。既然會反轉,那麼反轉後的位置就變了呀。
比如
3
2 3 1
他們sort以後變成1 2 3.
此時找1,初始位置是3,反轉之後變成1 3 2,然後刪除節點1,變成 3 2
然後再找2,初始位置是1,但是此時1號位置是3 而不是2了。
後來想了一想,Splay的存放是放在一個靜態數組,我們反轉只是反轉他的ch[x][0-1]。但是他自身存放的位置是不會變的。
所以只管去除數組中的第id號元素就可以了。
還有一個大問題!!!為什麼這題用rotate會超時,用zigzag就不會啊。二者的區別是什麼啊。也是看了愛醬的博客才發現的。。。
#include#include #include #include #define inf 0x3f3f3f3f #define maxn 122222 #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 rev[maxn]; struct node { int num,id; bool operator <(const node &cmp)const { if(num!=cmp.num)return num e)return; int mid=(s+e)>>1; New(x,f,mid); if(s mid)build(ch[x][1],mid+1,e,x); pushup(x); } inline void zig(int x){//左旋 int y=pre[x], z=pre[y]; ch[y][1]=ch[x][0]; pre[ch[x][0]]=y; ch[x][0]=y; pre[y]=x; pre[x]=z; if(z) ch[z][ch[z][1]==y]=x; pushup(y); } inline void zag(int x){//右旋 int y=pre[x], z=pre[y]; ch[y][0]=ch[x][1]; pre[ch[x][1]]=y; ch[x][1]=y; pre[y]=x; pre[x]=z; if(z) ch[z][ch[z][1]==y]=x; pushup(y); } inline void zigzig(int x){ int y=pre[x], z=pre[y], fz=pre[z]; ch[z][1]=ch[y][0]; pre[ch[y][0]]=z; ch[y][1]=ch[x][0]; pre[ch[x][0]]=y; pre[z]=y; ch[y][0]=z; pre[y]=x; ch[x][0]=y; pre[x]=fz; if(fz) ch[fz][ch[fz][1]==z]=x; pushup(z); pushup(y); } inline void zagzag(int x){ int y=pre[x], z=pre[y], fz=pre[z]; ch[z][0]=ch[y][1]; pre[ch[y][1]]=z; ch[y][0]=ch[x][1]; pre[ch[x][1]]=y; pre[z]=y; ch[y][1]=z; pre[y]=x; ch[x][1]=y; pre[x]=fz; if(fz) ch[fz][ch[fz][1]==z]=x; pushup(z); pushup(y); } inline void zigzag(int x){ int y=pre[x], z=pre[y], fz=pre[z]; ch[y][1]=ch[x][0]; pre[ch[x][0]]=y; ch[z][0]=ch[x][1]; pre[ch[x][1]]=z; pre[y]=pre[z]=x; ch[x][0]=y; ch[x][1]=z; pre[x]=fz; if(fz) ch[fz][ch[fz][1]==z]=x; pushup(z); pushup(y); } inline void zagzig(int x){ int y=pre[x], z=pre[y], fz=pre[z]; ch[y][0]=ch[x][1]; pre[ch[x][1]]=y; ch[z][1]=ch[x][0]; pre[ch[x][0]]=z; pre[y]=pre[z]=x; ch[x][1]=y; ch[x][0]=z; pre[x]=fz; if(fz) ch[fz][ch[fz][1]==z]=x; pushup(z); pushup(y); } void Splay(int x, int goal){ int y, z; pushdown(x); while(pre[x]!=goal){ if(pre[pre[x]]==goal){ y=pre[x]; pushdown(y); pushdown(x); if(ch[y][1]==x) zig(x); else zag(x); } else{ y=pre[x]; z=pre[y]; pushdown(z); pushdown(y); pushdown(x); if(ch[z][1]==y){ if(ch[y][1]==x) zigzig(x); else zagzig(x); } else{ if(ch[y][0]==x) zagzag(x); else zigzag(x); } } } pushup(x); if(pre[x]==0) root=x; } /* inline void Rotate(int x,int kind) { int y=pre[x]; pushdown(y); pushdown(x); ch[y][!kind]=ch[x][kind]; pre[ch[x][kind]]=y; pre[x]=pre[y]; if(pre[x])ch[pre[y]][ch[pre[y]][1]==y]=x; 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 RorateTo(int k,int goal) { int r=root; pushdown(r); while(siz[ch[r][0]]!=k) { if(k