COJ 1002 WZJ的数据结构(二)(splay模板)

我的LCC,LCT,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(‘\n‘)
  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;}

刘汝佳的Splay跑得虽然快但局限性太大:

  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 }

搜索

复制

时间: 2024-12-28 01:32:17

COJ 1002 WZJ的数据结构(二)(splay模板)的相关文章

COJ 0979 WZJ的数据结构(负二十一)

WZJ的数据结构(负二十一) 难度级别:C: 运行时间限制:5000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 请你实现一个数据结构,完成这样的功能: 给你一个N个点的图,初始状态无边. 每次加入一条双向边(u,v,w),若加入后没有构成一棵生成树,输出“Not Yet”,否则输出当前最小生成树的权值. 输入 第一行两个正整数N,M.表示有N个点M个操作.接下来M行每行三个正整数u,v,w. 输出 每次加入一条双向边(u,v,w),若加入后没有构成一棵生成

COJ 0981 WZJ的数据结构(负十九)树综合

WZJ的数据结构(负十九) 难度级别:E: 运行时间限制:15000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 WZJ的数据结构中有很多都是关于树的.这让很多练习模板的同学还要找来找去很不爽,于是WZJ跟小伙伴们一块商量如何将这些题汇拢到一块去: WZJ:为了大家简单,我规定一开始是一棵有根树. LZJ:那我一定得加上换根操作喽. XJR:链信息修改,链信息增加,链信息翻倍,维护链信息的最大,最小,总和肯定很好做. CHX:子树信息修改,子树信息增加,子树

COJ 0999 WZJ的数据结构(负一)

WZJ的数据结构(负一) 难度级别:D: 运行时间限制:1000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 输入N个模板串Pi和文本串T,输出每个模板串Pi在T中出现了多少次. 输入 第一行为一个正整数N.接下来N行为Pi.最后一行为T 输出 输出N行,第i行为模板串Pi在T中出现的次数. 输入示例 5aabbaabaaababababa 输出示例 54445 其他说明 1<=sigma(|Pi|)<=10000001<=|T|<=10000

COJ 0970 WZJ的数据结构(负三十)树分治

WZJ的数据结构(负三十) 难度级别:D: 运行时间限制:1000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 给你一棵N个点的无根树,点和边上均有权值.请你设计一个数据结构,回答M次操作. 1 x v:对于树上的每一个节点y,如果将x.y在树上的距离记为d,那么将y节点的权值加上d*v. 2 x:询问节点x的权值. 输入 第一行为一个正整数N.第二行到第N行每行三个正整数ui,vi,wi.表示一条树边从ui到vi,距离为wi.第N+1行为一个正整数M.最后

COJ 1010 WZJ的数据结构(十) 线段树区间操作

传送门:http://oj.cnuschool.org.cn/oj/home/problem.htm?problemID=1001 WZJ的数据结构(十) 难度级别:D: 运行时间限制:3000ms: 运行空间限制:51200KB: 代码长度限制:2000000B 试题描述 请你设计一个数据结构,高效执行以下过程: #include<iostream>using namespace std;const int maxn=100010;int A[maxn];int tp,ql,qr,v;int

COJ 0995 WZJ的数据结构(负五)区间操作

WZJ的数据结构(负五) 难度级别:C: 运行时间限制:1000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 请你设计一个数据结构,完成以下功能: 给定一个大小为N的整数组A,要求你回答执行M次操作.操作分两种: 操作1:每次操作给你l,r,v三个参数,求Al至Ar中值<=v的个数. 操作2:每次操作给你l,r,v三个参数,将Al至Ar中每个数的值+v. 输入 第一行为一个正整数N.第二行为N个整数Ai.第三行为一个正整数M.接下来M行每行4个正整数t,l,

COJ 1010 WZJ的数据结构(十) 线段树的地狱

传送门:http://oj.cnuschool.org.cn/oj/home/problem.htm?problemID=1001 WZJ的数据结构(十) 难度级别:D: 运行时间限制:3000ms: 运行空间限制:51200KB: 代码长度限制:2000000B 试题描述 请你设计一个数据结构,高效执行以下过程: #include<iostream>using namespace std;const int maxn=100010;int A[maxn];int tp,ql,qr,v;int

COJ 0967 WZJ的数据结构(负三十三)

WZJ的数据结构(负三十三) 难度级别:E: 运行时间限制:7000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 请你设计一个数据结构,完成以下功能: 给定一个大小为N的整数组A,要求你回答执行N次操作.操作分两种: 操作1:每次操作给你l,r,v三个参数,求Al至Ar中值<=v的个数. 操作2:每次操作给你l,r,v三个参数,将Al至Ar所有数的值设为v. 输入 第一行为一个正整数N.第二行为N个整数Ai.接下来N行每行4个正整数t,l,r,v.若t=2表

COJ 0985 WZJ的数据结构(负十五)(限定区域不同数)

传送门:http://oj.cnuschool.org.cn/oj/home/addSolution.htm?problemID=955 试题描述: CHX有一个问题想问问大家.给你一个长度为N的数列A,请你找到两个位置L,R,使得A[L].A[L+1].…….A[R]中没有重复的数,输出R-L+1的最大值. 以上是附中联赛加试的一道题.WZJ觉得这道题太水了,改了改题目: WZJ有一个问题想问问大家.给你一个长度为N的数列A,你要回答M次问题.每次问题给你两个正整数ql,qr.请你找到两个位置