权值线段树
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 5e5+10;
int n,m,a[MAXN],x,y,op;
//Segment tree
#define l(x) tree[x].ls
#define r(x) tree[x].rs
#define sum(x) tree[x].sum
int Segmentsum;
struct SegmentTree{
int l,r,len,ls,rs,sum,maxpos=INT_MIN,minpos=INT_MAX;
}tree[MAXN*8];
void build(int l,int r){
Segmentsum++;
tree[Segmentsum].l = l;
tree[Segmentsum].r = r;
tree[Segmentsum].len = r-l+1;
tree[Segmentsum].sum = 0;
}
void pushup(int x){
if(tree[x].l==tree[x].r) return;
sum(x) = sum(l(x))+sum(r(x));
tree[x].maxpos=max(tree[l(x)].maxpos,tree[r(x)].maxpos);
tree[x].minpos=min(tree[l(x)].minpos,tree[r(x)].minpos);
}
void pushdown(int x){
if(tree[x].l==tree[x].r) return;
int mid = (tree[x].l+tree[x].r)>>1;
if(!l(x)){
build(tree[x].l,mid);
l(x) = Segmentsum;
}
if(!r(x)){
build(mid+1,tree[x].r);
r(x) = Segmentsum;
}
}
void modify(int k,int x,int y){
if(tree[k].l>x||tree[k].r<x) return;
if(tree[k].l==x&&tree[k].r==x){
tree[k].sum += y;
return;
}
pushdown(k);
modify(l(k),x,y);
modify(r(k),x,y);
pushup(k);
}
int ask_less(int k,int x){
if(tree[k].l>x) return 0;
if(tree[k].r<x) return tree[k].sum;
if(!tree[k].sum) return 0;
pushdown(k);
int ans = ask_less(l(k),x)+ask_less(r(k),x);
pushup(k);
return ans;
}
int ask_small(int k,int p){
if(tree[k].l == tree[k].r) return tree[k].l;
pushdown(k);
if(p<=tree[l(k)].sum){
return ask_small(l(k),p);
}
return ask_small(r(k),p-sum(l(k)));
}
signed main(){
// freopen("P3369_7.in","r",stdin);
// freopen("P3369_7.ans","w",stdout);
scanf("%d",&n);
build(-1e7,1e7);
for(int i = 1;i<=n;i++){
scanf("%d%d",&op,&x);
if(op==1){
modify(1,x,1);
}else if(op==2){
modify(1,x,-1);
}else if(op==3){
printf("%d\n",ask_less(1,x)+1);
}else if(op==4){
printf("%d\n",ask_small(1,x));
}else if(op==5){
printf("%d\n",ask_small(1,ask_less(1,x)));
}else if(op==6){
printf("%d\n",ask_small(1,ask_less(1,x+1)+1));
}
}
return 0;
}
Splay
普通版
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1e6;
int n,m,minn,anss;
//Splay
int root,tot;
struct BST_Splay{
int data;
int fath;
int lson;
int rson;
int sum;
int k;
}tree[MAXN];
void pushup(int x){
tree[x].sum = tree[tree[x].lson].sum+tree[tree[x].rson].sum+tree[x].k;
}
void zig(int x){
int y = tree[x].fath;
int z = tree[y].fath;
int B = tree[x].rson;
tree[x].rson = y;
tree[y].fath = x;
tree[y].lson = B;
if(B) tree[B].fath = y;
tree[x].fath = z;
if(z){
if(y==tree[z].lson) tree[z].lson = x;
else tree[z].rson = x;
}else root = x;
pushup(y);
pushup(x);
}
void zag(int x){
int y = tree[x].fath;
int z = tree[y].fath;
int B = tree[x].lson;
tree[x].lson = y;
tree[y].fath = x;
tree[y].rson = B;
if(B) tree[B].fath = y;
tree[x].fath = z;
if(z){
if(y==tree[z].lson) tree[z].lson = x;
else tree[z].rson = x;
}else root = x;
pushup(y);
pushup(x);
}
void splay(int x){
auto fa = tree[x].fath;
while(fa){
auto p = tree[fa].fath;
if(p){
if(tree[fa].lson == x){
if(tree[p].lson == fa){
zig(fa);
zig(x);
}else{
zig(x);
zag(x);
}
}else{
if(tree[p].lson == fa){
zag(x);
zig(x);
}else{
zag(fa);
zag(x);
}
}
}else{
if(tree[fa].lson == x){
zig(x);
}else{
zag(x);
}
}
fa = tree[x].fath;
}
}
// 36 r = 36
void insert(int x){
if(!root){
root = ++tot;
tree[tot].data = x;
tree[tot].sum++;
tree[tot].k++;
return;
}
auto now = root;
bool lr = false;
++tot;
while(true){
if(x < tree[now].data){
if(tree[now].lson){
now = tree[now].lson;
}else{
lr = 1;
break;
}
}else if(x==tree[now].data){
tree[now].k++;
splay(now);
return;
}else{
if(tree[now].rson){
now = tree[now].rson;
}else{
lr = 0;
break;
}
}
}
if(lr){
tree[now].lson = tot;
tree[tot].fath = now;
tree[tot].data = x;
}else{
tree[now].rson = tot;
tree[tot].fath = now;
tree[tot].data = x;
}
tree[tot].sum++;
tree[tot].k++;
splay(tot);
}
void Delete(int x){
auto now = root;
if(!now) return;
while(true){
if(x < tree[now].data){
if(tree[now].lson){
now = tree[now].lson;
}else{
break;
}
}else if(x == tree[now].data){
tree[now].k--;
if(tree[now].k>0){
splay(now);
break;
}
splay(now);
root = tree[now].lson;
tree[tree[now].lson].fath = 0;
int tmp = root;
while(true){
if(tree[tmp].rson) tmp = tree[tmp].rson;
else break;
}
splay(tmp);
if(tmp) tree[tmp].rson = tree[now].rson;
else root = tree[now].rson;
tree[tree[now].rson].fath = tmp;
pushup(tmp);
break;
}else{
if(tree[now].rson) now = tree[now].rson;
else break;
}
}
}
int pre(int x){
int now = root;
int ans = 0;
while(now){
if(x>tree[now].data){
ans = tree[now].data;
now = tree[now].rson;
}else{
now = tree[now].lson;
}
}
return ans;
}
int suc(int x){
int now = root;
int ans = 0;
while(now){
if(x<tree[now].data){
ans = tree[now].data;
now = tree[now].lson;
}else{
now = tree[now].rson;
}
}
return ans;
}
int Rank(int x){
int now = root;
int ans = 0;
while(now){
if(x==tree[now].data){
ans = now;
break;
}
if(x<=tree[now].data){
ans = now;
now = tree[now].lson;
}else{
now = tree[now].rson;
}
}
int p = ans;
splay(p);
return tree[tree[p].lson].sum;
}
int find_kth(int k){
int now = root;
if(!now) return -1;
while(now){
if(tree[tree[now].lson].sum+tree[tree[now].rson].sum+tree[now].k<k) return -1;
if(k-tree[now].k<=tree[tree[now].rson].sum&&k-1>=tree[tree[now].rson].sum){
return tree[now].data;
}
if(k>tree[tree[now].rson].sum){
k-=tree[now].k;
k -= tree[tree[now].rson].sum;
now = tree[now].lson;
}else{
now = tree[now].rson;
}
}
return -1;
}
signed main(){
scanf("%d",&n);
for(int i = 1;i<=n;i++){
int x,op;
scanf("%d%d",&op,&x);
switch (op) {
case 1:
insert(x);
break;
case 2:
Delete(x);
break;
case 3:
printf("%d \n",Rank(x)+1);
break;
case 4:
printf("%d \n",find_kth(tree[root].sum-x+1));
break;
case 5:
printf("%d \n",pre(x));
break;
default:
printf("%d \n",suc(x));
}
}
return 0;
}
精简版
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int MAXN = 3e5+10;
struct SPLAY{
int son[2],all;
int num,sum,fath;
}tree[MAXN];
int root,cnt;
void pushup(int id){
tree[id].all = tree[tree[id].son[0]].all+tree[tree[id].son[1]].all+tree[id].sum;
}
void rotate(int id){
int is = tree[tree[id].fath].son[1]==id;
int fath = tree[id].fath;
if(tree[id].fath){
int k = tree[tree[tree[id].fath].fath].son[1]==tree[id].fath;
tree[tree[tree[id].fath].fath].son[k] = id;
tree[id].fath = tree[tree[id].fath].fath;
}
tree[fath].son[is] = tree[id].son[is^1];
tree[tree[id].son[is^1]].fath = fath;
tree[id].son[is^1] = fath;
tree[fath].fath = id;
pushup(fath);
pushup(id);
}
void splay(int x,int y){
while(tree[x].fath!=y){
int p = tree[x].fath;
if(tree[p].fath==y){
rotate(x);
}else{
if((tree[p].son[1]==x)==(tree[tree[p].fath].son[1]==p)) rotate(p);
else rotate(x);
rotate(x);
}
}
if(!y) root = x;
}
void insert(int x){
int now = root,fath = 0,k;
while(now){
tree[now].all++;
if(tree[now].num==x){
tree[now].sum++;
splay(now,0);
return;
}
if(tree[now].num>x){
fath = now;k = 0;
now = tree[now].son[0];
}else{
fath = now;k = 1;
now = tree[now].son[1];
}
}
now = ++cnt;
if(fath){
tree[now].fath = fath;
tree[fath].son[k] = now;
}else root = now;
tree[now].num = x;
tree[now].sum = 1;
tree[now].all = 1;
splay(now,0);
}
void find(int x){
int now = root;
while(now){
if(tree[now].num==x) break;
if(tree[now].num>x) now = tree[now].son[0];
else now = tree[now].son[1];
}
splay(now,0);
}
void Delete(int x){
find(x);
if(!(--tree[root].sum)){
tree[tree[root].son[0]].fath = 0;
tree[tree[root].son[1]].fath = 0;
if(tree[root].son[0]){
int k = tree[root].son[1];
int now = tree[root].son[0],fath=0;
while(now){
fath = now;
now = tree[fath].son[1];
}
splay(fath,0);
tree[fath].son[1] = k;
tree[k].fath = fath;
tree[root].all += tree[k].all;
}else root = tree[root].son[1];
}
}
int pre(int k){
insert(k);
find(k);
int now = tree[root].son[0];
int fath = 0;
while(now){
fath = now;
now = tree[now].son[1];
}
int ans = tree[fath].num;
Delete(k);
return ans;
}
int suc(int k){
insert(k);
find(k);
int now = tree[root].son[1];
int fath = 0;
while(now){
fath = now;
now = tree[now].son[0];
}
int ans = tree[fath].num;
Delete(k);
return ans;
}
int Rank(int k){
insert(k);
find(k);
int ans = tree[tree[root].son[0]].all+1;
Delete(k);
return ans;
}
int kth(int k){
int now = root;
while(now){
if(tree[tree[now].son[0]].all<k){
if(tree[tree[now].son[0]].all+tree[now].sum>=k) return tree[now].num;
k -= tree[tree[now].son[0]].all+tree[now].sum;
now = tree[now].son[1];
}
else now = tree[now].son[0];
}
return -1;
}
signed main(){
int T;
scanf("%lld",&T);
while(T--){
int opt,x;
scanf("%lld%lld",&opt,&x);
switch(opt){
case 1:{
insert(x);
break;
}
case 2:{
Delete(x);
break;
}
case 3:{
printf("%lld\n",Rank(x));
break;
}
case 4:{
printf("%lld\n",kth(x));
break;
}
case 5:{
printf("%lld\n",pre(x));
break;
}
case 6:{
printf("%lld\n",suc(x));
break;
}
}
}
return 0;
}
Treap
带旋Treap
#include<bits/stdc++.h>
#define random XJYISXXS
using namespace std;
const int MAXN = 1e5+10;
int random(){
return 1ll*rand()*rand()%(int)1e9;
}
int n,k;
//Treap
struct Treap{
int lson,rson,fath,sum,k;
int data,priority;
}tree[MAXN];
int root,tot;
void pushup(int x){
tree[x].sum = tree[tree[x].lson].sum+tree[tree[x].rson].sum+tree[x].k;
}
void zag(int x){
int y = tree[x].fath;
int z = tree[y].fath;
//son
tree[y].rson = tree[x].lson;
if(tree[x].lson) tree[tree[x].lson].fath = y;
tree[x].lson = y;
if(z){
if(tree[z].lson == y) tree[z].lson = x;
else tree[z].rson = x;
}else root = x;
//fath
tree[y].fath = x;
tree[x].fath = z;
pushup(y);
pushup(x);
}
void zig(int x){
int y = tree[x].fath;
int z = tree[y].fath;
//son
tree[y].lson = tree[x].rson;
if(tree[x].rson) tree[tree[x].rson].fath = y;
tree[x].rson = y;
if(z){
if(tree[z].lson == y) tree[z].lson = x;
else tree[z].rson = x;
}else root = x;
//fath
tree[y].fath = x;
tree[x].fath = z;
pushup(y);
pushup(x);
}
void insert(int x){
++tot;
if(!root){
tree[tot].sum = 1;
tree[tot].k = 1;
tree[tot].data = x;
tree[tot].priority = random();
root = tot;
return;
}
int now = root;
bool bj = 1;//l1 r0
while(now){
tree[now].sum++;
if(x<tree[now].data){
if(tree[now].lson){
now = tree[now].lson;
}else{
bj = 1;
break;
}
}else if(x>tree[now].data){
if(tree[now].rson){
now = tree[now].rson;
}else{
bj = 0;
break;
}
}else{
tot--;
tree[now].k++;
return;
}
}
tree[tot].fath = now;
if(bj) tree[now].lson = tot;
else tree[now].rson = tot;
tree[tot].data = x;
tree[tot].k++;
tree[tot].sum++;
tree[tot].priority = random();
int son = tot;
while(now){
if(tree[now].priority>tree[son].priority){
if(tree[now].lson==son){
zig(son);
}else{
zag(son);
}
now = tree[son].fath;
}else break;
}
}
int find_kth(int k){
int now = root;
while(now){
if(k-tree[now].k<=tree[tree[now].lson].sum&&tree[tree[now].lson].sum<=k-1){
return tree[now].data;
}
if(tree[tree[now].lson].sum>=k){
now = tree[now].lson;
}else{
k -= tree[now].k;
k -= tree[tree[now].lson].sum;
now = tree[now].rson;
}
}
return -1;
}
int pre(int x){
int now = root,ans = 0;
while(now){
if(x<tree[now].data){
now = tree[now].lson;
}else if(x>tree[now].data){
ans = tree[now].data;
now = tree[now].rson;
}else{
now = tree[now].lson;
if(now){
while(now){
if(tree[now].rson) now = tree[now].rson;
else break;
}
return tree[now].data;
}
}
}
return ans;
}
int suc(int x){
int now = root,ans = 0;
while(now){
if(x<tree[now].data){
ans = tree[now].data;
now = tree[now].lson;
}else if(x>tree[now].data){
now = tree[now].rson;
}else{
now = tree[now].rson;
if(now){
while(now){
if(tree[now].lson) now = tree[now].lson;
else break;
}
return tree[now].data;
}
}
}
return ans;
}
int find(int x){
int now = root;
while(now){
if(x<tree[now].data){
now = tree[now].lson;
}else if(x>tree[now].data){
now = tree[now].rson;
}else{
return now;
}
}
return -1;
}
void Delete(int x){
int now = find(x);
tree[now].k--;
if(tree[now].k){
int tmp = now;
while(tmp){
pushup(tmp);
tmp = tree[tmp].fath;
}
return;
}
while(tree[now].lson&&tree[now].rson){
if(tree[tree[now].lson].priority<tree[tree[now].rson].priority){
zig(tree[now].lson);
}else{
zag(tree[now].rson);
}
}
int tmp = now;
while(tmp){
pushup(tmp);
tmp = tree[tmp].fath;
}
if(tree[now].lson){
if(tree[tree[now].fath].lson == now) tree[tree[now].fath].lson = tree[now].lson;
else tree[tree[now].fath].rson = tree[now].lson;
tree[tree[now].lson].fath = tree[now].fath;
}else{
if(tree[tree[now].fath].lson == now) tree[tree[now].fath].lson = tree[now].rson;
else tree[tree[now].fath].rson = tree[now].rson;
tree[tree[now].rson].fath = tree[now].fath;
}
}
int Rank(int x){
int now = root,ans = 0;
while(now){
if(x<tree[now].data){
now = tree[now].lson;
}else if(x>tree[now].data){
ans += tree[tree[now].lson].sum;
ans += tree[now].k;
now = tree[now].rson;
}else{
ans += tree[tree[now].lson].sum;
now = tree[now].rson;
}
}
return ans;
}
signed main(){
srand(time(NULL));
scanf("%d",&n);
for(int i = 1;i<=n;i++){
int opt,x;
scanf("%d%d",&opt,&x);
if(i==8){
int x = 0;
}
switch (opt) {
case 1:
insert(x);
break;
case 2:
Delete(x);
break;
case 3:
if(x==223489){
int y = 0;
}
printf("%d\n",Rank(x)+1);
break;
case 4:
printf("%d\n",find_kth(x));
break;
case 5:
printf("%d\n",pre(x));
break;
case 6:
printf("%d\n",suc(x));
break;
}
}
return 0;
}
FHQ_Treap
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 2e5+10;
const int INF = 0x3f3f3f3f;
//FHQ_treap
int root,tot;
struct FHQ_treap{
int lson,rson,sum;
int data,priority;
}tree[MAXN];
int New_Node(int x){
++tot;
tree[tot].data = x;
tree[tot].priority = rand();
tree[tot].sum++;
return tot;
}
void pushup(int x){
tree[x].sum = tree[tree[x].lson].sum+tree[tree[x].rson].sum+1;
}
void split_value(int x,int k,int &l,int &r){
if(!x){
l = r = 0;
return;
}
if(tree[x].data<=k){
l = x;
split_value(tree[x].rson,k,tree[x].rson,r);
}else{
r = x;
split_value(tree[x].lson,k,l,tree[x].lson);
}
pushup(x);
}
int merge(int l,int r){
if(!l||!r) return l|r;
if(tree[l].priority<tree[r].priority){
tree[l].rson = merge(tree[l].rson,r);
pushup(l);
return l;
}else{
tree[r].lson = merge(l,tree[r].lson);
pushup(r);
return r;
}
}
void insert(int x){
int lroot,rroot;
split_value(root,x-1,lroot,rroot);
root = merge(merge(lroot,New_Node(x)),rroot);
}
int kth(int root,int k){
int now = root;
while(now){
int ln = tree[tree[now].lson].sum+1;
if(ln==k)return tree[now].data;
if(ln<k) now = tree[now].rson,k-=ln;
else now = tree[now].lson;
}
return INF;
}
void Delete(int x){
int lroot,rroot,temp;
split_value(root,x-1,lroot,rroot);
split_value(rroot,x,temp,rroot);
temp = merge(tree[temp].lson,tree[temp].rson);
root = merge(merge(lroot,temp),rroot);
}
void Delete(int l,int r){
int lroot,rroot,temp;
split_value(root,l-1,lroot,rroot);
split_value(rroot,r,temp,rroot);
root = merge(lroot,rroot);
}
int pre(int x){
int lroot,rroot;
split_value(root,x-1,lroot,rroot);
int ans = kth(lroot,tree[lroot].sum);
root = merge(lroot,rroot);
return ans;
}
int suc(int x){
int lroot,rroot;
split_value(root,x,lroot,rroot);
int ans = kth(rroot,1);
root = merge(lroot,rroot);
return ans;
}
int same_as(int x){
int lroot,rroot,temp;
split_value(root,x-1,lroot,rroot);
split_value(rroot,x,temp,rroot);
int ans = tree[temp].sum;
root = merge(merge(lroot,temp),rroot);
return ans;
}
void DeBug(int &root){
if(!root) return;
int lroot,rroot,temp;
split_value(root,tree[root].data-1,lroot,rroot);
split_value(rroot,tree[root].data,temp,rroot);
DeBug(lroot);
printf("%d %d\n",tree[temp].data,tree[temp].sum);
DeBug(rroot);
root = merge(merge(lroot,temp),rroot);
}
int Rank(int x){
int lroot,rroot;
split_value(root,x-1,lroot,rroot);
int ans = tree[lroot].sum;
root = merge(lroot,rroot);
return ans;
}
//Other
int n,ans;
signed main(){
srand(time(NULL));
scanf("%d",&n);
for(int i = 1;i<=n;i++){
int opt,x;
scanf("%d%d",&opt,&x);
switch (opt) {
case 1:
insert(x);
break;
case 2:
Delete(x);
break;
case 3:
printf("%d\n",Rank(x)+1);
break;
case 4:
printf("%d\n",kth(root,x));
break;
case 5:
printf("%d\n",pre(x));
break;
case 6:
printf("%d\n",suc(x));
break;
}
}
return 0;
}
tag
洛谷
、LOJ
数据结构
、线段树
、权值线段树
、动态开点线段树
、平衡树
、Treap
、FHQ_Treap
、Splay
、BST