HDU-3487 Play with Chain Splay tee区間反転、移動

35453 ワード

タイトルリンク:http://acm.hdu.edu.cn/showproblem.php?pid=3487
1つの数列に対して2つの操作があります:1.CUT a b c、まずa-b区間の数を取り出して、それからそれらを取り出した後のc番目の数の後ろに置きます.2.FLIP a bは、区間a-bの数を反転させる.1つ目の操作については,2回の区間移動を行い,a−1番目の数Splayからルートノード,b+1番目の数Splayからrootの右の息子,ch[ch[root][1]][0]はその区間を表し,その後それらを除去し,移動区間でc番目の数Splayからroot,c+1番目の数Splayからrootの右の息子,さらに先ほどの区間を加算すればよい.2回目の操作はノードごとに価格を設定し、息子が反転しているかどうかを示し、怠惰な操作マークで更新を遅らせます.の
  1 //STATUS:C++_AC_578MS_6452KB

  2 #include <functional>

  3 #include <algorithm>

  4 #include <iostream>

  5 //#include <ext/rope>

  6 #include <fstream>

  7 #include <sstream>

  8 #include <iomanip>

  9 #include <numeric>

 10 #include <cstring>

 11 #include <cassert>

 12 #include <cstdio>

 13 #include <string>

 14 #include <vector>

 15 #include <bitset>

 16 #include <queue>

 17 #include <stack>

 18 #include <cmath>

 19 #include <ctime>

 20 #include <list>

 21 #include <set>

 22 #include <map>

 23 using namespace std;

 24 //using namespace __gnu_cxx;

 25 //define

 26 #define pii pair<int,int>

 27 #define mem(a,b) memset(a,b,sizeof(a))

 28 #define lson l,mid,rt<<1

 29 #define rson mid+1,r,rt<<1|1

 30 #define PI acos(-1.0)

 31 //typedef

 32 typedef __int64 LL;

 33 typedef unsigned __int64 ULL;

 34 //const

 35 const int N=300010;

 36 const int INF=0x3f3f3f3f;

 37 const int MOD=100000,STA=8000010;

 38 const LL LNF=1LL<<60;

 39 const double EPS=1e-8;

 40 const double OO=1e15;

 41 const int dx[4]={-1,0,1,0};

 42 const int dy[4]={0,1,0,-1};

 43 const int day[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};

 44 //Daily Use ...

 45 inline int sign(double x){return (x>EPS)-(x<-EPS);}

 46 template<class T> T gcd(T a,T b){return b?gcd(b,a%b):a;}

 47 template<class T> T lcm(T a,T b){return a/gcd(a,b)*b;}

 48 template<class T> inline T lcm(T a,T b,T d){return a/d*b;}

 49 template<class T> inline T Min(T a,T b){return a<b?a:b;}

 50 template<class T> inline T Max(T a,T b){return a>b?a:b;}

 51 template<class T> inline T Min(T a,T b,T c){return min(min(a, b),c);}

 52 template<class T> inline T Max(T a,T b,T c){return max(max(a, b),c);}

 53 template<class T> inline T Min(T a,T b,T c,T d){return min(min(a, b),min(c,d));}

 54 template<class T> inline T Max(T a,T b,T c,T d){return max(max(a, b),max(c,d));}

 55 //End

 56 

 57 #define Key_value ch[ch[root][1]][0]

 58 int pre[N],ch[N][2];  //       ,  ,    (0    ,1    ),   ,    

 59 int sz[N],st[N];   //

 60 int root,tot,top;   //   ,     ,     

 61 //      

 62 int key[N];

 63 bool rev[N];

 64 int n,m;

 65 //debug  copy from hh

 66 void Treaval(int x) {

 67     if(x) {

 68         Treaval(ch[x][0]);

 69         printf("  %2d:    %2d     %2d     %2d size = %2d rev = %2d key = %2d
",x,ch[x][0],ch[x][1],pre[x],sz[x],rev[x],key[x]); 70 Treaval(ch[x][1]); 71 } 72 } 73 void debug() {printf("%d
",root);Treaval(root);} 74 // Debug 75 // 76 void NewNode(int &x,int fa,int k) 77 { 78 if(top)x=st[--top]; 79 else x=++tot; 80 key[x]=k; 81 pre[x]=fa; 82 sz[x]=1; 83 rev[x]=0; 84 ch[x][0]=ch[x][1]=0; // 85 } 86 87 void Push_Up(int x) 88 { 89 sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+1; 90 } 91 92 void Push_Down(int x) 93 { 94 if(rev[x]){ 95 rev[ch[x][0]]^=1; 96 rev[ch[x][1]]^=1; 97 swap(ch[x][0],ch[x][1]); 98 rev[x]=0; 99 } 100 } 101 // ,kind 1 ,kind 0 102 void Rotate(int x,int kind) 103 { 104 int y=pre[x],z=pre[y]; 105 Push_Down(y); 106 Push_Down(x); // y , x 107 // SBT, 108 ch[y][!kind]=ch[x][kind]; 109 pre[ch[x][kind]]=y; 110 // 111 if(z)ch[z][ch[z][1]==y]=x; 112 pre[x]=z; 113 ch[x][kind]=y; 114 pre[y]=x; 115 Push_Up(y); // y , x ,x Push_Down, x 116 } 117 //Splay , r goal 118 void Splay(int x,int goal) 119 { 120 int y,z,kind; 121 while(pre[x]!=goal){ 122 // ,goal 0 , 123 y=pre[x]; 124 Push_Down(pre[y]);Push_Down(y);Push_Down(x); // , , !! 125 if(pre[y]==goal){ 126 Rotate(x,ch[y][0]==x); 127 } 128 else { 129 kind=ch[pre[y]][0]==y; 130 // 131 if(ch[y][kind]==x){ 132 Rotate(x,!kind); 133 Rotate(x,kind); 134 } 135 // 136 else { 137 Rotate(y,kind); 138 Rotate(x,kind); 139 } 140 } 141 } 142 // 143 Push_Up(x); 144 if(goal==0)root=x; 145 } 146 147 void RotateTo(int k,int goal) 148 { 149 int x=root; 150 Push_Down(x); 151 while(sz[ch[x][0]]!=k){ 152 if(sz[ch[x][0]]>k) 153 x=ch[x][0]; 154 else { 155 k-=sz[ch[x][0]]+1; 156 x=ch[x][1]; 157 } 158 Push_Down(x); 159 } 160 Splay(x,goal); 161 } 162 // , , 163 void BuildTree(int &x,int l,int r,int fa) 164 { 165 if(l>r)return; 166 int mid=(l+r)>>1; 167 NewNode(x,fa,mid); 168 BuildTree(ch[x][0],l,mid-1,x); 169 BuildTree(ch[x][1],mid+1,r,x); 170 Push_Up(x); 171 } 172 173 void Init() 174 { 175 root=top=tot=0; 176 ch[0][0]=ch[0][1]=sz[0]=pre[0]=rev[0]=0; 177 178 NewNode(root,0,-1); 179 NewNode(ch[root][1],root,-1); 180 BuildTree(Key_value,1,n,ch[root][1]); 181 Push_Up(ch[root][1]); 182 Push_Up(root); 183 } 184 185 int ok; 186 void print(int u) 187 { 188 if(!u)return; 189 Push_Down(u); 190 print(ch[u][0]); 191 if(key[u]>0){ 192 if(ok){printf("%d",key[u]);ok=0;} 193 else printf(" %d",key[u]); 194 } 195 print(ch[u][1]); 196 } 197 198 void Cut(int a,int b,int c) 199 { 200 RotateTo(a-1,0); 201 RotateTo(b+1,root); 202 int s=Key_value; 203 Key_value=0; 204 Splay(ch[root][1],0); 205 RotateTo(c,0); 206 RotateTo(c+1,root); 207 Key_value=s; 208 pre[s]=ch[root][1]; 209 Splay(Key_value,0); 210 } 211 212 void Flip(int a,int b) 213 { 214 RotateTo(a-1,0); 215 RotateTo(b+1,root); 216 rev[Key_value]^=1; 217 } 218 219 int main() 220 { 221 // freopen("in.txt","r",stdin); 222 int i,j,a,b,c; 223 char s[10]; 224 while(~scanf("%d%d",&n,&m) && (n>=0 || m>=0)) 225 { 226 if(n==1){ 227 printf("1
"); 228 continue; 229 } 230 Init(); 231 while(m--){ 232 scanf("%s",s); 233 if(s[0]=='C'){ 234 scanf("%d%d%d",&a,&b,&c); 235 Cut(a,b,c); 236 } 237 else { 238 scanf("%d%d",&a,&b); 239 Flip(a,b); 240 } 241 } 242 ok=1; 243 print(root); 244 putchar('
'); 245 } 246 return 0; 247 }