codevs1743
http://codevs.cn/problem/1743/
splay区间翻转。
数字在原序列中的位置保存在splay的data[]中。splay中点的编号为原序列的数字大小。
每次pushdown只在find时进行就行,因为find结束时splay只会改动i点祖先的信息,而其余时候没有splay操作了。
记得加个+INF 一个-INF。
1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 #define N 400000 5 #define INF 2000000000 6 int lazy[N],s[N][3],f[N],cnt[N],data[N],root,total;//son:1left 2right 7 int fi,num,p,q,le[N],m,n,i,j,ans; 8 char opt; 9 struct lbz 10 { 11 int a,b; 12 }x[N]; 13 bool cmp(lbz a,lbz b) 14 { 15 return a.a<b.a; 16 } 17 void rotate(int x,int w)//w:1leftZag 2rightZig 18 { 19 int y; 20 y=f[x]; 21 cnt[y]=cnt[y]-cnt[x]+cnt[s[x][w]]; 22 cnt[x]=cnt[x]-cnt[s[x][w]]+cnt[y]; 23 s[y][3-w]=s[x][w]; 24 if (s[x][w]!=0) 25 f[s[x][w]]=y; 26 f[x]=f[y]; 27 if (f[y]!=0) 28 if (y==s[f[y]][1]) 29 s[f[y]][1]=x; 30 else 31 s[f[y]][2]=x; 32 f[y]=x; 33 s[x][w]=y; 34 } 35 void splay(int x,int t) 36 { 37 int y; 38 while (f[x]!=t) 39 { 40 y=f[x]; 41 if (f[y]==t) 42 if (x==s[y][1]) 43 rotate(x,2); 44 else 45 rotate(x,1); 46 else 47 if (y==s[f[y]][1]) 48 if (x==s[y][1]) 49 { 50 rotate(y,2); 51 rotate(x,2); 52 } 53 else 54 { 55 rotate(x,1); 56 rotate(x,2); 57 } 58 else 59 if (x==s[y][2]) 60 { 61 rotate(y,1); 62 rotate(x,1); 63 } 64 else 65 { 66 rotate(x,2); 67 rotate(x,1); 68 } 69 } 70 if (f[x]==0) root=x; 71 } 72 73 int sea(int x,int w) 74 { 75 int t; 76 t=x; 77 while (1) 78 { 79 if (data[t]==w) break; 80 if (w<=data[t]) 81 { 82 if (s[t][1]==0) break; 83 t=s[t][1]; 84 } 85 else 86 { 87 if (s[t][2]==0) break; 88 t=s[t][2]; 89 } 90 91 } 92 splay(t,0); 93 return t; 94 } 95 void add(int w) 96 { 97 int x; 98 if (total==0) 99 { 100 total++; 101 f[1]=0;cnt[1]=1;data[1]=w;root=1; 102 return; 103 } 104 x=root; 105 while(1) 106 { 107 cnt[x]++; 108 if (w<=data[x]) 109 { 110 if (s[x][1]==0) break; 111 x=s[x][1]; 112 } 113 else 114 { 115 if (s[x][2]==0) break; 116 x=s[x][2]; 117 } 118 } 119 total++; 120 data[total]=w; 121 f[total]=x; 122 cnt[total]=1; 123 if (w<=data[x]) 124 s[x][1]=total; 125 else 126 s[x][2]=total; 127 splay(total,0); 128 } 129 130 void pushdown(int x) 131 { 132 lazy[x]^=1; 133 lazy[s[x][1]]^=1; 134 lazy[s[x][2]]^=1; 135 swap(s[x][1],s[x][2]); 136 } 137 int find(int k,int w)//w=1 Kthsmall;w=2 Kthbig 138 { 139 int i,t; 140 i=root;t=k; 141 if (lazy[i]==1) 142 pushdown(i); 143 144 while (t!=cnt[s[i][w]]+1) 145 { 146 147 if (t>cnt[s[i][w]]+1) 148 { 149 t-=cnt[s[i][w]]+1; 150 i=s[i][3-w]; 151 } 152 else 153 i=s[i][w]; 154 if (lazy[i]==1) 155 pushdown(i); 156 } 157 splay(i,0); 158 return i; 159 } 160 161 int rec(int l,int r) 162 { 163 int ll,rr; 164 ll=find(l,1); 165 rr=find(r+2,1); 166 splay(ll,0); 167 splay(rr,ll); 168 lazy[s[rr][1]]^=1; 169 } 170 int main() 171 { 172 scanf("%d",&n); 173 for (i=1;i<=n;i++) 174 { 175 scanf("%d",&x[i].a); 176 x[i].b=i; 177 } 178 sort(x+1,x+1+n,cmp); 179 for (i=1;i<=n;i++) 180 add(x[i].b); 181 add(1000000000); 182 add(-1000000000); 183 while (1) 184 { 185 fi=find(2,1); 186 if (fi==1) break; 187 rec(1,fi); 188 ans++; 189 } 190 printf("%d\n",ans); 191 return 0; 192 }
-------------------------------------------------------------------------
花有重开日,人无再少年