FhqTreap各种操作模板大赏
$\ \ \ \ \ \ \ \,$关于Splay操作的复习笔记:
$\ \ \ \ \ \ \ \,$一些平衡树操作和都是一样的,详见【Splay各种操作模板大赏】。
结构
1 | struct fhq_Treap{ |
- $\tt root$ :根;
- $\tt cnt$ :下标大小;
- $\tt key[]$ :关键值;
- $\tt ls[]\&rs[]$ :左右儿子;
- $\tt sum[]$ :子树权值;
- $\tt val[]$ :节点权值;
- $\tt size[]$ :节点大小;
- $\tt lazy[]$ :下传标记。
基本操作
- 手写随机($Rand$)
1
2
3
4int Rand(){
static int seed=233;
return seed=int(seed*48271LL%20020207);
} - 标记上传 ($pushup$)
1
2
3
4void pushup(int rt){
size[rt]=size[lson]+size[rson]+1;
sum[rt]=sum[lson]+sum[rson]+val[rt];
} - 标记下传 ($pushdown$),根据情况会不一样
1
2
3
4
5
6void pushdown(int rt){
if(!lazy[rt])return;
swap(lson,rson);
lazy[lson]^=1;lazy[rson]^=1;
lazy[rt]=0;
} - 分裂($split$)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20//权值
void split(int rt,int x,int &a,int &b){
if(!rt) a=0,b=0;
else{
pushdown(rt);
if(val[rt]<=x)a=rt,split(rson,x,rs[a],b);
else b=rt,split(lson,x,a,ls[b]);
pushup(rt);
}
}
//位置
void split(int rt,int x,int &a,int &b){
if(!rt) a=0,b=0;
else{
pushdown(rt);
if(size[ls[rt]]<x)a=rt,split(rson,x-size[ls[rt]]-1,rs[a],b);
else b=rt,split(lson,x,a,ls[b]);
pushup(rt);
}
} - 合并($merge$)
1
2
3
4
5int merge(int x,int y){
if(!x||!y) return x+y;
if(key[x]<key[y]){pushdown(x);rs[x]=merge(rs[x],y);pushup(x);return x;}
else {pushdown(y);ls[y]=merge(x,ls[y]);pushup(y);return y;}
}
修改
- 新建节点 ($newnode$)
1
2
3
4int newnode(int v){
sum[++cnt]=val[cnt]=v;size[cnt]=1;key[cnt]=Rand();
return cnt;
} - 插入($Insert$)
1
2
3
4
5
6void Insert(int x,int v){
int a,b;
split(root,x,a,b);
int rt=newnode(v);
root=merge(merge(a,rt),b);
} - 删除($Delete$)
1
2
3
4
5
6void Delete(int x){
int a,b,c;
split(root,x,a,b);split(a,x-1,a,c);
c=merge(ls[c],rs[c]);
root=merge(merge(a,c),b);
} - 区间修改(翻转)($revse$)
1
2
3
4
5
6
7void Reverse(int l,int r){
int x,y,z;
split(root,r,x,z);
split(x,l-1,x,y);
lazy[y]^=1;
root=merge(merge(x,y),z);
}
询问
查找排名第k的值($QueryRank$)
1
2
3
4
5
6
7
8int QueryRank(int x){
int rt=root;
while(rt){
if(x==size[lson]+1)return val[rt];
if(size[lson]>=x)rt=lson;
else x-=size[lson]+1,rt=rson;
}
}查找某个值的排名($Rank$)
1
2
3
4
5
6
7
8int Rank(int x){
int rt=root,res=1;
while(rt){
if(val[rt]>=x)rt=lson;
else res+=size[lson]+1,rt=rson;
}
return res;
}- 前驱($Numpre$)
1
int Numpre(int x){return QueryRank(Rank(x)-1);}
- 后继($Numnex$)
1
int Numnex(int x){return QueryRank(Rank(x+1));}
- 区间查询(权值和)($Numnex$)
1
2
3
4
5
6
7
8long long Query(int l,int r){
int x,y,z;
split(root,r,x,z);
split(x,l-1,x,y);
long long ans=sum[y];
root=merge(merge(x,y),z);
return ans;
}
两个模板题:
- P3369 【模板】普通平衡树
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130// luogu-judger-enable-o2
using namespace std;
const int inf=0x7fffffff;
const double eps=1e-10;
const double pi=acos(-1.0);
//char buf[1<<15],*S=buf,*T=buf;
//char getch(){return S==T&&(T=(S=buf)+fread(buf,1,1<<15,stdin),S==T)?0:*S++;}
inline int read(){
int x=0,f=1;char ch;ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') f=0;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch&15);ch=getchar();}
if(f)return x;else return -x;
}
const int N=1e5+10;
struct fhq_Treap{
int Rand(){
static int seed=233;
return seed=int(seed*48271LL%20020207);
}
int size[N],key[N],val[N];
int ls[N],rs[N],cnt,sum[N];
int root;
bool lazy[N];
void pushup(int rt){
size[rt]=size[lson]+size[rson]+1;
sum[rt]=sum[lson]+sum[rson]+val[rt];
}
int clone(int b){
++cnt;
size[cnt]=size[b];key[cnt]=key[b];val[cnt]=val[b];
ls[cnt]=ls[b];rs[cnt]=rs[b],lazy[cnt]=lazy[b];sum[cnt]=sum[b];
return cnt;
}
void pushdown(int rt) {
if(!lazy[rt])return;
swap(lson,rson);
lazy[lson]^=1;lazy[rson]^=1;
lazy[rt]=0;
}
int merge(int x,int y){
if(!x||!y) return x+y;
if(key[x]<key[y]){pushdown(x);rs[x]=merge(rs[x],y);pushup(x);return x;}
else {pushdown(y);ls[y]=merge(x,ls[y]);pushup(y);return y;}
}
//权值
void split(int rt,int x,int &a,int &b){
if(!rt) a=0,b=0;
else{
pushdown(rt);
if(val[rt]<=x)a=rt,split(rson,x,rs[a],b);
else b=rt,split(lson,x,a,ls[b]);
pushup(rt);
}
}
void Insert(int x){
int a,b;
split(root,x,a,b);
val[++cnt]=x;size[cnt]=1;key[cnt]=Rand();
root=merge(merge(a,cnt),b);
}
void Delete(int x){
int a,b,c;
split(root,x,a,b);split(a,x-1,a,c);
c=merge(ls[c],rs[c]);
root=merge(merge(a,c),b);
}
int Rank(int x){
int rt=root,res=1;
while(rt){
if(val[rt]>=x)rt=lson;
else res+=size[lson]+1,rt=rson;
}
return res;
}
int QueryRank(int x){
int rt=root;
while(rt){
if(x==size[lson]+1)return val[rt];
if(size[lson]>=x)rt=lson;
else x-=size[lson]+1,rt=rson;
}
}
int Numpre(int x){return QueryRank(Rank(x)-1);}
int Numnex(int x){return QueryRank(Rank(x+1));}
void Reverse(int l,int r){
int x,y,z;
split(root,r,x,z);
split(x,l-1,x,y);
lazy[y]^=1;
root=merge(merge(x,y),z);
}
long long Query(int l,int r){
int x,y,z;
split(root,r,x,z);
split(x,l-1,x,y);
long long ans=sum[y];
root=merge(merge(x,y),z);
return ans;
}
}Fhq;
int main()
{
int n=read();
while(n--){
int opt=read(),x=read();
if(opt==1){Fhq.Insert(x);continue;}
if(opt==2){Fhq.Delete(x);continue;}
if(opt==3){printf("%d\n",Fhq.Rank(x));continue;}
if(opt==4){printf("%d\n",Fhq.QueryRank(x));continue;}
if(opt==5){printf("%d\n",Fhq.Numpre(x));continue;}
if(opt==6){printf("%d\n",Fhq.Numnex(x));continue;}
}
return 0;
} - P3391 【模板】文艺平衡树(Splay)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
using namespace std;
const int inf=0x7fffffff;
const double eps=1e-10;
const double pi=acos(-1.0);
//char buf[1<<15],*S=buf,*T=buf;
//char getch(){return S==T&&(T=(S=buf)+fread(buf,1,1<<15,stdin),S==T)?0:*S++;}
inline int read(){
int x=0,f=1;char ch;ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') f=0;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch&15);ch=getchar();}
if(f)return x;else return -x;
}
const int N=1e5+10;
int a[N],n,m;
struct fhq_Treap{
int Rand(){
static int seed=233;
return seed=int(seed*48271LL%20020207);
}
int size[N],key[N],val[N],w[N];
int ls[N],rs[N],cnt;
int root;
bool lazy[N];
void pushup(int rt){
size[rt]=size[lson]+size[rson]+1;
}
void pushdown(int rt) {
if(!lazy[rt])return;
swap(lson,rson);
lazy[lson]^=1;lazy[rson]^=1;
lazy[rt]=0;
}
int merge(int x,int y){
if(!x||!y) return x+y;
if(key[x]<key[y]){pushdown(x);rs[x]=merge(rs[x],y);pushup(x);return x;}
else {pushdown(y);ls[y]=merge(x,ls[y]);pushup(y);return y;}
}
//位置
void split(int rt,int x,int &a,int &b){
if(!rt) a=0,b=0;
else{
pushdown(rt);
if(size[ls[rt]]<x)a=rt,split(rson,x-size[ls[rt]]-1,rs[a],b);
else b=rt,split(lson,x,a,ls[b]);
pushup(rt);
}
}
void Insert(int x,int v){
int a,b;
split(root,x,a,b);++cnt;
val[cnt]=v;size[cnt]=1;key[cnt]=Rand();
root=merge(merge(a,cnt),b);
}
void Reverse(int l,int r){
int x,y,z;
split(root,r,x,z);
split(x,l-1,x,y);
lazy[y]^=1;
root=merge(merge(x,y),z);
}
}Fhq;
void write(int rt){
Fhq.pushdown(rt);
if(Fhq.lson)write(Fhq.lson);
printf("%d ",Fhq.val[rt]);
if(Fhq.rson)write(Fhq.rson);
}
int main()
{
n=read();m=read();
for(int i=1;i<=n;i++)Fhq.Insert(i-1,i);
while(m--){
int l=read(),r=read();
Fhq.Reverse(l,r);
}
write(Fhq.root);
printf("\n");
return 0;
}