标签:style blog http color os io ar for art
区间翻转 一脸Splay。
第一次做区间翻转。一开始懒惰标记表示当前这可子树都需要翻转。这样就有个问题:旋转的状态的不一定是正确的(rotate传的参数不一定正确)。
然后参考ac代码。联系线段树的lazy标记,每次跟新某个区间的时候,该线段区间肯定要先跟新,再在改区间节点打上标记,表示后面的子区间节点需要跟新。所以,翻转标记表示他两个儿子子树需要翻转,但是两个儿子的状态已经是正确的。
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #define keyTree (ch[ch[root][1]][0]) 5 using namespace std; 6 7 const int maxn=102222; 8 typedef long long LL; 9 10 struct node{ 11 int x; 12 int id; 13 bool operator<(const node &a)const { 14 return x<a.x||x==a.x&&id<a.id; 15 } 16 }; 17 struct SplayTree{ 18 int sz[maxn]; 19 int ch[maxn][2]; 20 int pre[maxn]; 21 int root,top1; 22 23 inline void Rotate(int x,int f){ 24 int y=pre[x]; 25 push_down(y); 26 push_down(x); 27 ch[y][!f]=ch[x][f]; 28 pre[ch[x][f]]=y; 29 pre[x]=pre[y]; 30 if(pre[x])ch[pre[y]][ch[pre[y]][1]==y]=x; 31 ch[x][f]=y; 32 pre[y]=x; 33 push_up(y); 34 } 35 inline void Splay(int x,int goal){ 36 push_down(x); 37 while(pre[x]!=goal){ 38 if(pre[pre[x]]==goal){ 39 push_down(pre[x]); 40 push_down(x); 41 Rotate(x,ch[pre[x]][0]==x); 42 }else{ 43 int y=pre[x],z=pre[y]; 44 int f=(ch[z][0]==y); 45 push_down(z); 46 push_down(y); 47 push_down(x); 48 if(ch[y][f]==x){ 49 Rotate(x,!f),Rotate(x,f); 50 }else{ 51 Rotate(y,f),Rotate(x,f); 52 } 53 } 54 } 55 push_up(x); 56 if(goal==0) root=x; 57 } 58 inline void RotateTo(int k,int goal){ 59 int x=root; 60 push_down(x); 61 while(sz[ch[x][0]]+1!=k){ 62 if(k<=sz[ch[x][0]]){ 63 x=ch[x][0]; 64 }else{ 65 k-=(sz[ch[x][0]]+1); 66 x=ch[x][1]; 67 } 68 push_down(x); 69 } 70 Splay(x,goal); 71 } 72 73 inline void debug(int x){ 74 push_down(x); 75 if(ch[x][0])debug(ch[x][0]); 76 printf("@%d %d ",x,val[x]); 77 if(ch[x][1])debug(ch[x][1]); 78 } 79 inline void NewNode(int &x,int id){ 80 x=id; 81 ++top1; 82 ch[x][0]=ch[x][1]=pre[x]=0; 83 sz[x]=1; 84 85 flip[x]=0; 86 } 87 inline void push_down(int x){ 88 if(flip[x]){ 89 flip[ch[x][0]]=1-flip[ch[x][0]]; 90 flip[ch[x][1]]=1-flip[ch[x][1]]; 91 rever(ch[x][0]); 92 rever(ch[x][1]); 93 flip[x]=0; 94 } 95 } 96 inline void rever(int x){ 97 swap(ch[x][0],ch[x][1]); 98 } 99 inline void push_up(int x){ 100 sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+1; 101 } 102 103 inline void makeTree(int &x,int l,int r,int f){ 104 if(l>r)return ; 105 int m=(l+r)>>1; 106 NewNode(x,m); 107 makeTree(ch[x][0],l,m-1,x); 108 makeTree(ch[x][1],m+1,r,x); 109 pre[x]=f; 110 if(f==0)root=x; 111 push_up(x); 112 } 113 void init(int n){ 114 ch[0][0]=ch[0][1]=pre[0]=sz[0]=0; 115 116 root=top1=0; 117 118 for(int i=1;i<=n;i++){ 119 scanf("%d",&a[i].x); 120 a[i].id=i; 121 } 122 sort(a+1,a+n+1); 123 for(int i=1;i<=n;i++){ 124 pos[i]=a[i].id; 125 //cout<<pos[i]<<" "; 126 val[pos[i]]=i; 127 } 128 //cout<<endl; 129 makeTree(keyTree,1,n,0); 130 131 } 132 /*void update(int l,int r,LL c){ 133 RotateTo(l-1,0); 134 RotateTo(r+1,root); 135 136 val[keyTree]+=c; 137 sum[keyTree]+=c*sz[keyTree]; 138 add[keyTree]+=c; 139 push_up(ch[root][1]); 140 push_up(root); 141 }*/ 142 int dfs(int x){ 143 push_down(x); 144 if(ch[x][0]==0)return x; 145 146 return dfs(ch[x][0]); 147 } 148 void query(int n){ 149 150 for(int i=1;i<n;i++){ 151 Splay(pos[i],0); 152 printf("%d ",i+sz[ch[root][0]]); 153 rever(ch[root][0]); 154 flip[ch[root][0]]=1-flip[ch[root][0]]; 155 156 if(ch[root][1]==0){ 157 root=ch[root][0]; 158 pre[root]=0; 159 }else{ 160 int last=dfs(ch[root][1]); 161 Splay(last,root); 162 ch[last][0]=ch[root][0]; 163 pre[ch[root][0]]=last; 164 root=last; 165 pre[root]=0; 166 } 167 push_up(root); 168 } 169 printf("%d\n",n); 170 } 171 int flip[maxn]; 172 int pos[maxn]; 173 int val[maxn]; 174 node a[maxn]; 175 }spt; 176 int main() 177 { 178 int n; 179 180 while(scanf("%d",&n),n){ 181 spt.init(n); 182 spt.query(n); 183 } 184 return 0; 185 }
标签:style blog http color os io ar for art
原文地址:http://www.cnblogs.com/youyouyou/p/3960216.html