COJ 1002 WZJのデータ構造(二)(splayテンプレート)
37243 ワード
私のLCC、LCT、Splayフォーマットがようやく統一されました.
また.この形式のSplayは標準的なSplayです.(どのように鑑定しますか?Splay関数は変数のnodeだけを伝えたらいいですか?)、劉汝佳白書のSplayは本当に突っ込みたくないです.制限が大きすぎて、勉強しないでください.
はい、修理の数列を書きに行きます...
標準Splayテンプレート:
検索
コピー
また.この形式のSplayは標準的なSplayです.(どのように鑑定しますか?Splay関数は変数のnodeだけを伝えたらいいですか?)、劉汝佳白書のSplayは本当に突っ込みたくないです.制限が大きすぎて、勉強しないでください.
はい、修理の数列を書きに行きます...
標準Splayテンプレート:
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*ch[2],*fa;
14 int x,siz;bool rev;char c;
15 node(){x=0;siz=1;rev=false;}
16 void revt(){swap(ch[0],ch[1]);rev^=1;return;}
17 inline void down(){
18 if(rev){CH{ch[d]->revt();}rev=false;}return;
19 }
20 inline void update(){
21 siz=1;CH{siz+=ch[d]->siz;}return;
22 }
23 }Splay[maxn],*root=&Splay[0];int cnt=0;void print(node*x);
24 inline int parent(node*x,node*&y){return (y=x->fa)?y->ch[1]==x?1:y->ch[0]==x?0:-1:-1;}
25 inline void rotate(node*x){
26 node*y,*z;int d1=parent(x,y),d2=parent(y,z);
27 if(y->ch[d1]=x->ch[d1^1]) y->ch[d1]->fa=y;
28 y->fa=x;x->fa=z;x->ch[d1^1]=y;
29 if(d2!=-1) z->ch[d2]=x;
30 y->update();return;
31 }
32 void pushdown(node*x){
33 static node*s[maxn];int top=0;
34 for(node*y;;x=y){
35 s[top++]=x;y=x->fa;
36 if(!y||(y->ch[0]!=x&&y->ch[1]!=x)) break;
37 } while(top--) s[top]->down();return;
38 }
39 node*splay(node*x){
40 pushdown(x);node*y,*z;int d1,d2;
41 while(true){
42 if((d1=parent(x,y))<0) break;
43 if((d2=parent(y,z))<0){rotate(x);break;}
44 if(d1==d2) rotate(y),rotate(x);
45 else rotate(x),rotate(x);
46 } x->update();return x;
47 }
48 node*find(node*x,int rank){
49 x->down();int kth=1; if(x->ch[0]) kth=x->ch[0]->siz+1;
50 if(kth==rank) return x;
51 if(kth>rank) return find(x->ch[0],rank);
52 else return find(x->ch[1],rank-kth);
53 }
54 void split(node*&x,node*&y,int a){//
55 if(!a){y=x;x=NULL;return;}
56 x=splay(find(x,a));
57 y=x->ch[1];x->ch[1]=NULL;x->update();return;
58 }
59 void split(node*&x,node*&y,node*&z,int a,int b){//
60 split(x,z,b);split(x,y,a-1);
61 return;
62 }
63 void join(node*&x,node*y){
64 if(!x){x=y;return;}
65 if(!y) return;
66 x=splay(find(x,x->siz));
67 x->ch[1]=y;y->fa=x;x->update();return;
68 }
69 void join(node*&x,node*y,node*z){
70 join(y,z);join(x,y);return;
71 }
72 void reverse(int a,int b){
73 node*x,*y;split(root,x,y,a,b);x->revt();join(root,x,y);return;
74 }
75 char s[maxn];
76 void build(node*&x,int L,int R){
77 if(L>R) return;x=&Splay[++cnt];
78 int M=L+R>>1;x->c=s[M];
79 build(x->ch[0],L,M-1);build(x->ch[1],M+1,R);
80 if(x->ch[0]) x->ch[0]->fa=x;
81 if(x->ch[1]) x->ch[1]->fa=x;
82 x->update();return;
83 }
84 inline int read(){
85 int x=0,sig=1;char ch=getchar();
86 while(!isdigit(ch)){if(ch=='-')sig=-1;ch=getchar();}
87 while(isdigit(ch))x=10*x+ch-'0',ch=getchar();
88 return x*sig;
89 }
90 void write(int x){
91 if(x==0){putchar('0');return;}if(x<0)putchar('-'),x=-x;
92 int len=0,buf[15];while(x)buf[len++]=x%10,x/=10;
93 for(int i=len-1;i>=0;i--)putchar(buf[i]+'0');return;
94 }
95 void printer(node*x){
96 if(!x) return;
97 x->down();
98 printer(x->ch[0]);
99 putchar(x->c);
100 printer(x->ch[1]);
101 return;
102 }
103 void init(){
104 scanf("%s",s);
105 build(root,0,strlen(s)-1);
106 int Q=read(),L,R;
107 while(Q--){L=read();R=read();reverse(L,R);}
108 printer(root);
109 return;
110 }
111 void work(){
112 return;
113 }
114 void print(){
115 return;
116 }
117 int main(){init();work();print();return 0;}
劉汝佳のスピードは速いが、制限が大きすぎる: 1 #include<cstdio>
2 #include<cctype>
3 #include<cstring>
4 #include<algorithm>
5 using namespace std;
6 inline void read(int& x)
7 {
8 x=0; char ch=getchar();int sig=1;
9 while(!isdigit(ch)) {if(ch=='-') sig=-1;ch=getchar();}
10 while(isdigit(ch)) x=x*10+ch-'0',ch=getchar();
11 x*=sig;
12 }
13 const int maxn=100010;
14 struct Node
15 {
16 Node* ch[2];
17 int s,flip;
18 char c;
19 int cmp(int k)
20 {
21 if(k==ch[0]->s+1) return -1;
22 return k<=ch[0]->s?0:1;
23 }
24 void maintain(){s=ch[0]->s+ch[1]->s+1;}
25 void pushdown()
26 {
27 if(flip)
28 {
29 ch[0]->flip^=1;ch[1]->flip^=1;
30 swap(ch[0],ch[1]);
31 flip=0;
32 }
33 }
34 }*null=new Node(),nodes[maxn];
35 int tot;
36 void rotate(Node* &o,int d)
37 {
38 Node* k=o->ch[d^1];o->ch[d^1]=k->ch[d];k->ch[d]=o;
39 o->maintain();k->maintain();o=k;
40 }
41 void splay(Node* &o,int k)
42 {
43 o->pushdown();
44 int d=o->cmp(k);
45 if(d) k-=o->ch[0]->s+1;
46 if(d!=-1)
47 {
48 Node* p=o->ch[d];p->pushdown();
49 int d2=p->cmp(k);
50 int k2=d2?k-p->ch[0]->s-1:k;
51 if(d2!=-1)
52 {
53 splay(p->ch[d2],k2);
54 if(d==d2) rotate(o,d^1);
55 else rotate(o->ch[d],d);
56 }
57 rotate(o,d^1);
58 }
59 }
60 void print(Node* &o)
61 {
62 if(o==null) return;
63 o->pushdown();
64 print(o->ch[0]);
65 printf("%c",o->c);
66 print(o->ch[1]);
67 }
68 char s[maxn];
69 void build(Node* &o,int L,int R)
70 {
71 o=null;
72 if(L>R) return;
73 int M=L+R>>1;
74 o=&nodes[tot++];
75 o->c=s[M];o->flip=0;
76 build(o->ch[0],L,M-1);build(o->ch[1],M+1,R);
77 o->maintain();
78 }
79 Node *root,*o,*left,*mid,*right;
80 void merge(Node* &left,Node* &right)
81 {
82 if(left==null) left=right;
83 else
84 {
85 splay(left,left->s);
86 left->ch[1]=right;
87 left->maintain();
88 }
89 }
90 void split(Node* &o,Node* &left,Node* &right,int k)
91 {
92 if(!k) left=null,right=o;
93 else
94 {
95 splay(o,k);
96 left=o;
97 right=left->ch[1];
98 left->ch[1]=null;
99 left->maintain();
100 }
101 }
102 int main()
103 {
104 scanf("%s",s);
105 build(root,0,strlen(s)-1);
106 int Q,L,R;
107 read(Q);
108 while(Q--)
109 {
110 read(L),read(R);
111 split(root,left,o,L-1);
112 split(o,mid,right,R-L+1);
113 mid->flip^=1;
114 merge(left,mid);
115 merge(left,right);
116 root=left;
117 }
118 print(root);
119 return 0;
120 }
検索
コピー