20605移动盒子 |
难度级别:B; 运行时间限制:1000ms; 运行空间限制:51200KB; 代码长度限制:2000000B |
试题描述
|
你有一行盒子,从左到右依次编号为1,2,3,……,n。可以执行一下四种指令: |
输入
|
第一行包括两个正整数n和m,分别表示盒子个数和指令条数,接下来的m行,每行一条指令,如果是指令1、2或者3时,三部分间有一个空格分隔,如指令1 2 4表示将盒子2移动到盒子4的左边。
|
输出
|
一个正整数,表示所有奇数位置上盒子编号的数字之和。
|
输入示例
|
6 4
1 1 4 2 3 5 3 1 6 4 |
输出示例
|
12
|
其他说明
|
样例说明:当n=6时,在初始状态下执行1 1 4后,盒子序列为2 3 1 4 5 6,接下来执行2 3 5后,盒子序列变成2 1 4 5 3 6,再执行3 1 6,得到2 6 4 5 3 1,最终执行4,得到1 3 5 4 6 2。
0 < n, m < 100001 |
题解:赤裸裸的链表,可惜我没有写。我写的是splay tree你们怕不怕!!!
写完真的是太爽了。。。
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<algorithm> 5 #include<queue> 6 #include<cstring> 7 #define PAU putchar(' ') 8 #define ENT putchar(' ') 9 #define CH for(int d=0;d<=1;d++) if(ch[d]) 10 using namespace std; 11 const int maxn=100000+10; 12 struct node{ 13 node*fa,*ch[2]; 14 int c;bool rev;int siz; 15 node(){c=-1;rev=false;siz=1;} 16 void revt(){swap(ch[0],ch[1]);rev^=1;return;} 17 void update(){siz=1;CH{siz+=ch[d]->siz;}return;} 18 void down(){if(rev){CH{ch[d]->revt();}rev=false;}return;} 19 }Splay[maxn],*root;int cnt=0; 20 int parent(node*x,node*&y){return (y=x->fa)?y->ch[1]==x?1:y->ch[0]==x?0:-1:-1;} 21 void rotate(node*x){ 22 node*y,*z;int d1=parent(x,y),d2=parent(y,z); 23 if(y->ch[d1]=x->ch[d1^1]) y->ch[d1]->fa=y; 24 y->fa=x;x->fa=z;x->ch[d1^1]=y; 25 if(d2!=-1) z->ch[d2]=x; 26 y->update();return; 27 } 28 void pushdown(node*x){ 29 static node*s[maxn];int top=0; 30 for(node*y;;x=y){ 31 s[top++]=x;y=x->fa; 32 if(!y||(y->ch[0]!=x&&y->ch[1]!=x)) break; 33 } while(top--) s[top]->down();return; 34 } 35 node*splay(node*x){ 36 pushdown(x);node*y,*z;int d1,d2; 37 while(true){ 38 if((d1=parent(x,y))<0) break; 39 if((d2=parent(y,z))<0){rotate(x);break;} 40 if(d1==d2) rotate(y),rotate(x); 41 else rotate(x),rotate(x); 42 } x->update();return x; 43 } 44 node*find(node*x,int rank){ 45 x->down();int kth=1;if(x->ch[0]) kth=x->ch[0]->siz+1; 46 if(rank==kth) return x; 47 if(rank<kth) return find(x->ch[0],rank); 48 else return find(x->ch[1],rank-kth); 49 } 50 void split(node*&x,node*&y,int a){ 51 if(!a){y=x;x=NULL;return;} 52 x=splay(find(x,a));y=x->ch[1]; 53 x->ch[1]=NULL;if(y)y->fa=NULL;x->update();return; 54 } 55 void split(node*&x,node*&y,node*&z,int a,int b){ 56 split(x,z,b);split(x,y,a-1);return; 57 } 58 void join(node*&x,node*y){ 59 if(!x){x=y;return;}if(!y)return; 60 x=splay(find(x,x->siz));x->ch[1]=y; 61 if(y)y->fa=x;x->update();return; 62 } 63 void join(node*&x,node*y,node*z){ 64 join(y,z);join(x,y);return; 65 } 66 int A[maxn],n,Q; 67 void build(node*&x,int L,int R){ 68 if(L>R)return;int M=L+R>>1; 69 x=&Splay[cnt++];x->c=A[M]; 70 build(x->ch[0],L,M-1); 71 build(x->ch[1],M+1,R); 72 if(x->ch[0]) x->ch[0]->fa=x; 73 if(x->ch[1]) x->ch[1]->fa=x; 74 x->update();return; 75 } 76 void reverse(int L,int R){ 77 node*x,*y;split(root,x,y,L,R);x->revt();join(root,x,y);return; 78 } 79 node*findll(node*x,int a){ 80 if(!x) return NULL;x->down(); 81 if(x->c==a) return x; 82 node*t; 83 if((t=findll(x->ch[0],a))||(t=findll(x->ch[1],a))) return t; 84 return NULL; 85 } 86 void printer(node*x){ 87 if(!x){printf("NULL ");return;} 88 x->down(); 89 if(x->ch[0])printer(x->ch[0]); 90 printf("%d ",x->c); 91 if(x->ch[1])printer(x->ch[1]); 92 return; 93 } 94 int cz=1;long long sum=0; 95 void counter(node*x){ 96 if(!x){return;} 97 x->down(); 98 if(x->ch[0])counter(x->ch[0]); 99 if((cz++)&1) sum+=x->c; 100 if(x->ch[1])counter(x->ch[1]); 101 return; 102 } 103 node*findfa(node*x){ 104 while(x->fa) x=x->fa;return x; 105 } 106 int findpos(int a){ 107 for(int i=1;i<=n;i++) if(A[i]==a) return i; 108 return -1; 109 } 110 void split(node*&t1,node*&x,node*&t2,node*&y,node*&t3,int a,int b){ 111 splay(t1); 112 x=findll(t1,a),y=findll(t1,b); 113 splay(x);int kth1=1;if(x->ch[0]) kth1=x->ch[0]->siz+1; 114 splay(y);int kth2=1;if(y->ch[0]) kth2=y->ch[0]->siz+1; 115 if(kth1>kth2) swap(kth1,kth2); 116 splay(t1);split(t1,x,t2,kth1,kth1); 117 kth2-=kth1;split(t2,y,t3,kth2,kth2);return; 118 } 119 void join(node*&t1,node*x,node*t2,node*y,node*t3){ 120 join(t2,y,t3);join(t1,x,t2);return; 121 } 122 void swapnode(int a,int b){ 123 node*t1,*t2,*x,*y; 124 split(root,x,t1,y,t2,a,b); 125 join(root,y,t1,x,t2);return; 126 } 127 void shift(int a,int b,int tp){//1 right 0 left 128 node*t1,*t2,*x,*y; 129 split(root,x,t1,y,t2,a,b); 130 y->ch[tp]=x;x->fa=y;y->update(); 131 join(root,NULL,t1,y,t2);return; 132 } 133 inline int read(){ 134 int x=0,sig=1;char ch=getchar(); 135 while(!isdigit(ch)){if(ch=='-')sig=-1;ch=getchar();} 136 while(isdigit(ch))x=10*x+ch-'0',ch=getchar(); 137 return x*=sig; 138 } 139 inline void write(int x){ 140 if(x==0){putchar('0');return;}if(x<0)putchar('-'),x=-x; 141 int len=0,buf[15];while(x)buf[len++]=x%10,x/=10; 142 for(int i=len-1;i>=0;i--)putchar(buf[i]+'0');return; 143 } 144 inline void write(long long x){ 145 if(x==0){putchar('0');return;}if(x<0)putchar('-'),x=-x; 146 int len=0;long long buf[15];while(x)buf[len++]=x%10,x/=10; 147 for(int i=len-1;i>=0;i--)putchar(buf[i]+'0');return; 148 } 149 void init(){ 150 n=read();Q=read(); 151 for(int i=1;i<=n;i++) A[i]=i; 152 build(root,1,n);int tp,a,b; 153 while(Q--){ 154 tp=read(); 155 if(tp==4) root->revt(); 156 else{ 157 a=read();b=read(); 158 if(tp==3) swapnode(a,b); 159 else shift(a,b,tp-1); 160 } 161 } 162 counter(root); 163 write(sum); 164 return; 165 } 166 void work(){ 167 return; 168 } 169 void print(){ 170 return; 171 } 172 int main(){init();work();print();return 0;}