BZOJ 3506 机械排序臂 splay
这是宝宝第二次敲splay了(如果LCT不算的话),还好吧!为什么自己写的TLE了呢?找个时间写下对拍吧!暂时还是要学习别人的代码的。一开始的思路是找到最小的点后,返回距离,然后删掉。在这里更深刻地体会到了自己的天真无邪,too young too simple , (假设当前的根是我们要删除的)以为只要把左子节点的父亲修改为右子结点, 右子结点的左儿子设成左子结点,然后把右子结点更新为根就好。(有没有发现问题所在?,右子结点原来的左儿子怎么办?)那好问题出现了就要寻求解决的方法了,我是这样想的,在右子树里一直往左走,走到第一个没有左子结点的位置,返回其标号,然后我们再把它旋转到根,然后……(你懂的)。然而这个TLE了。 其实这还不是我最开始的我,最开始的我是这样的,弄了左右边界,然后发现边界都被我翻转了,(有没有感到我的愚蠢)。后来再次Orz了黄学长的代码,当然我自己是做了修改的。加油了。splay还是很重要的。(我不想做源程狗。)
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #define lc c[k][0] 5 #define rc c[k][1] 6 #define rep(i,j,k) for(int i = j; i <= k; i++) 7 #define maxn 100233 8 using namespace std; 9 10 struct node{ 11 int v, pos; 12 bool operator < (const node&rhs) const{ 13 return pos < rhs.pos; 14 } 15 } nod[maxn]; 16 17 bool cmp(node a,node b) 18 { 19 return a.v < b.v || (a.v == b.v && a.pos < b.pos ); 20 } 21 22 int read() 23 { 24 int s = 0, t = 1; char c = getchar(); 25 while( !isdigit(c) ){ 26 if( c == '-' ) t= -1; c = getchar(); 27 } 28 while( isdigit(c) ){ 29 s =s * 10 + c - '0'; c= getchar(); 30 } 31 return s * t; 32 } 33 34 int s[maxn], pa[maxn], c[maxn][2], mn[maxn], v[maxn], root; 35 bool rev[maxn]; 36 37 void pushdown(int k) 38 { 39 if( rev[k] ){ 40 rev[k] ^= 1, rev[lc] ^= 1, rev[rc] ^= 1; 41 swap(lc,rc); 42 } 43 } 44 45 void maintain(int k) 46 { 47 mn[k] = k; 48 if( v[mn[lc]] < v[mn[k]] ) mn[k] = mn[lc]; 49 if( v[mn[rc]] < v[mn[k]] ) mn[k] = mn[rc]; 50 s[k] = s[lc] + s[rc] + 1; 51 } 52 53 void rorate(int k,int &root) 54 { 55 int fa = pa[k], gfa = pa[fa]; 56 int l = c[fa][1] == k, r = l ^ 1; 57 if( fa != root ){ 58 c[gfa][c[gfa][1] == fa] = k; 59 } else root = k; 60 pa[fa] = k, pa[c[k][r]] = fa, pa[k] = gfa; 61 c[fa][l] = c[k][r], c[k][r] = fa; maintain(fa), maintain(k); 62 } 63 64 int q[maxn]; 65 void splay(int k,int &root) 66 { 67 int top = 0; q[++top] = k; 68 for(int x = k; x != root; x = pa[x] ) q[++top] = pa[x]; 69 while( top ) pushdown(q[top--]); 70 while( k != root ){ 71 int fa = pa[k], gfa = pa[fa]; 72 if( fa != root ) { 73 if( c[gfa][1] == fa ^ c[fa][1] == k ) rorate(k,root); 74 else rorate(fa,root); 75 } 76 rorate(k,root); 77 } 78 } 79 80 void build(int l,int r,int pre) 81 { 82 if( l > r ) return; 83 int mid = (l+r)>>1; 84 c[pre][pre < mid] = mid; pa[mid] = pre; v[mid] = nod[mid].v, mn[mid] = mid; 85 c[mid][0] = c[mid][1] = 0; 86 if( l < r ){ 87 build(l,mid-1,mid); build(mid+1,r,mid); 88 maintain(mid); 89 } else s[mid] = 1; 90 } 91 92 int rank(int x,int k) 93 { 94 if( rev[k] ) pushdown(k); 95 if( s[lc] >= x ) return rank(x,lc); 96 else if( s[lc] + 1 < x ) return rank(x-s[lc]-1,rc); 97 else return k; 98 } 99 100 int query_min(int x,int y) 101 { 102 x = rank(x,root), y = rank(y+2,root); 103 splay(x,root); splay(y,c[x][1]); 104 return mn[c[y][0]]; 105 } 106 107 void rever(int x,int y) 108 { 109 x = rank(x,root), y = rank(y+2,root); 110 splay(x,root); splay(y,c[x][1]); 111 rev[c[y][0]] ^= 1; 112 } 113 114 void out(int k) 115 { 116 if( lc ) out(lc); 117 cout<<v[k]<<endl; 118 if( rc ) out(rc); 119 } 120 121 int main() 122 { 123 int n; 124 while( scanf("%d", &n) && n ){ 125 v[0] = nod[1].v = nod[n+2].v = 0x7fffffff; 126 rep(i,2,n+1) nod[i].v = read(), nod[i].pos = i; 127 sort(nod+2,nod+2+n,cmp); root = (3+n)>>1; 128 rep(i,2,n+1) nod[i].v = i-1; 129 sort(nod+2,nod+2+n); build(1,n+2,0); //out(root); 130 rep(i,1,n){ 131 int q = query_min(i,n); splay(q,root); 132 printf("%d ", s[c[q][0]] ); 133 rever(i,s[c[q][0]]); 134 } 135 puts(""); 136 } 137 return 0; 138 }
————————————————