hdu 1890 Robotic Sort
很早就会了splay。。。但是这题一直没有AC....
解法:按照顺序把节点旋到根,然后给根的左儿子打个标记,删掉根...
疑问?最开始的时候直接去找根节点前趋和后继节点的标号,然后两个splay删掉根。。。一直没调出来,不知到为什么错,后来的时候通过select找rank就AC了。。。难道是树的形状和我预想的不对?不明。。
1 #include<cstdio> 2 #include<cstring> 3 #include<cmath> 4 #include<ctime> 5 #include<cstdlib> 6 #include<cassert> 7 #include<algorithm> 8 #include<iostream> 9 #include<string> 10 #include<deque> 11 #include<vector> 12 #include<queue> 13 #include<list> 14 #include<stack> 15 #include<set> 16 #include<map> 17 #include<bitset> 18 #pragma comment(linker, "/STACK:102400000,102400000") 19 using namespace std; 20 typedef long long ll; 21 typedef pair<int,int> pii; 22 const int N=(int)1e5+10; 23 int hash[N]; 24 int nn; 25 struct splaytree{ 26 int cnt,root; 27 int sz[N],ch[N][2],pre[N]; 28 int rev[N]; 29 void newnode(int &t,int val){ 30 t=hash[val]; 31 sz[t]=1; 32 ch[t][0]=ch[t][1]=pre[t]=0; 33 rev[t]=0; 34 } 35 void pushup(int x){ 36 sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+1; 37 } 38 void pushdown(int x){ 39 if(rev[x]){ 40 if(ch[x][0])rev[ch[x][0]]^=1; 41 if(ch[x][1])rev[ch[x][1]]^=1; 42 swap(ch[x][0],ch[x][1]); 43 rev[x]=0; 44 } 45 } 46 bool dir(int x){ 47 return ch[pre[x]][1]==x; 48 } 49 void link(int x,int y,int d){ 50 if(y)ch[y][d]=x; 51 if(x)pre[x]=y; 52 } 53 void rotate(int x){ 54 int y=pre[x];bool d=dir(x); 55 pushdown(y);pushdown(x); 56 link(x,pre[y],dir(y)); 57 link(ch[x][!d],y,d); 58 link(y,x,!d); 59 pushup(y); 60 } 61 void dfs(int x){ 62 if(x==0)return; 63 dfs(pre[x]); 64 pushdown(x); 65 } 66 void splay(int x,int goal){ 67 dfs(x); 68 while(pre[x]!=goal){ 69 if(pre[pre[x]]==goal)rotate(x); 70 else{ 71 if(dir(x)==dir(pre[x]))rotate(pre[x]); 72 else rotate(x); 73 rotate(x); 74 } 75 } 76 pushup(x); 77 if(0==goal)root=x; 78 } 79 void select(int k,int goal){ 80 int x=root;pushdown(x); 81 while(sz[ch[x][0]]+1!=k){ 82 if(sz[ch[x][0]]+1>k){ 83 x=ch[x][0]; 84 }else{ 85 k-=sz[ch[x][0]]+1; 86 x=ch[x][1]; 87 } 88 pushdown(x); 89 } 90 splay(x,goal); 91 } 92 void init(){ 93 cnt=root=0; 94 sz[0]=ch[0][0]=ch[0][1]=pre[0]=0; 95 } 96 void insert(int val){ 97 int x=root; 98 while(ch[x][1])x=ch[x][1]; 99 newnode(ch[x][1],val); 100 pre[ch[x][1]]=x; 101 splay(ch[x][1],root); 102 } 103 void debug(int x){ 104 // printf("x = %d left = %d right = %d pre = %d\n",x,ch[x][0],ch[x][1],pre[x]); 105 printf("%d ",x); 106 } 107 void all(int n){ 108 for(int i=1;i<=n;i++)debug(i); 109 } 110 void show(int x){ 111 if(x==0)return; 112 pushdown(x); 113 show(ch[x][0]); 114 debug(x); 115 show(ch[x][1]); 116 } 117 int solve(int x){ 118 splay(x,0); 119 int rank=sz[ch[x][0]]+1; 120 if(ch[x][0])rev[ch[x][0]]^=1; 121 if(sz[ch[x][0]]==0&&sz[ch[x][1]]!=0){ 122 root=ch[x][1]; 123 pre[ch[x][1]]=0; 124 }else if(sz[ch[x][0]]!=0&&sz[ch[x][1]]==0){ 125 select(rank-1,0); 126 ch[root][1]=0; 127 pushup(root); 128 }else if(sz[ch[x][0]]!=0&&sz[ch[x][1]]!=0){ 129 select(rank-1,0); 130 select(rank+1,root); 131 ch[ch[root][1]][0]=0; 132 pushup(ch[root][1]); 133 pushup(root); 134 }else{ 135 root=0; 136 } 137 return rank; 138 } 139 140 }spt; 141 struct node{ 142 int val,id; 143 bool operator<(const node &a)const{ 144 return val < a.val||(val==a.val&&id < a.id); 145 } 146 }s[N]; 147 int main(){ 148 int n; 149 while(~scanf("%d",&n)){ 150 nn=n; 151 if(n==0)return 0; 152 for(int i=1;i<=n;i++){ 153 scanf("%d",&s[i].val); 154 s[i].id=i; 155 } 156 sort(s+1,s+1+n); 157 for(int i=1;i<=n;i++) 158 hash[s[i].id]=i; 159 spt.init(); 160 for(int i=1;i<=n;i++){ 161 spt.insert(i); 162 } 163 int cur=0; 164 for(int i=1;i<=n;i++){ 165 int now = spt.solve(i); 166 if(i!=1)printf(" "); 167 printf("%d",cur+now); 168 cur++; 169 } 170 puts(""); 171 } 172 return 0; 173 }