split采用按权
/*
author:revolIA
submit:;
*/
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e6+5;
int l[maxn],r[maxn],val[maxn],Size[maxn];
int rom[maxn],cnt;
int root,opt,n,a,x,y,z;
void update(int x){Size[x] = 1+Size[l[x]]+Size[r[x]];}
int New(int x){
Size[++cnt] = 1;
val[cnt] = x;
rom[cnt] = rand() << 15 | rand();
return cnt;
}
void split(int u,int k,int &x,int &y){
if(!u){x = y = 0;return;}
if(val[u]<=k)x = u,split(r[u],k,r[u],y);
else y = u,split(l[u],k,x,l[u]);
update(u);
}
int Merge(int x,int y){
if(x*y == 0)return x+y;
if(rom[x]<rom[y]){
r[x] = Merge(r[x],y);
return update(x),x;
}else{
l[y] = Merge(x,l[y]);
return update(y),y;
}
}
int K_th(int u,int k){
if(k<=Size[l[u]])return K_th(l[u],k);
if(k == Size[l[u]]+1)return u;
return K_th(r[u],k-Size[l[u]]-1);
}
int main(){
srand(time(0));
scanf("%d",&n);
while(n--){
scanf("%d%d",&opt,&a);
if(opt == 1){
split(root,a,x,y);
root = Merge(Merge(x,New(a)),y);
}else if(opt == 2){
split(root,a,x,z);
split(x,a-1,x,y);
y = Merge(l[y],r[y]);//del y(a)
root = Merge(Merge(x,y),z);
}else if(opt == 3){
split(root,a-1,x,y);
printf("%d\n",Size[x]+1);
root = Merge(x,y);
}else if(opt == 4){
printf("%d\n",val[K_th(root,a)]);
}else if(opt == 5){
split(root,a-1,x,y);
printf("%d\n",val[K_th(x,Size[x])]);
root = Merge(x,y);
}else{
split(root,a,x,y);
printf("%d\n",val[K_th(y,1)]);
root = Merge(x,y);
}
}
return 0;
}
split采用按Size
/*
author:revolIA
submit:;
*/
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+5;
int l[maxn],r[maxn],val[maxn],Size[maxn];
int rom[maxn],cnt;
int flag[maxn];
int root,opt,n,m,a,x,y,z;
void push_up(int x){Size[x] = 1+Size[l[x]]+Size[r[x]];}
void push_down(int x){
swap(l[x],r[x]);
flag[l[x]] ^= 1;
flag[r[x]] ^= 1;
flag[x] = 0;
}
int New(int x){
Size[++cnt] = 1;
val[cnt] = x;
rom[cnt] = rand() << 15 | rand();
return cnt;
}
void split(int u,int k,int &x,int &y){
if(!u){x = y = 0;return;}
if(flag[u])push_down(u);
if(Size[l[u]]<k)x = u,split(r[u],k-Size[l[u]]-1,r[u],y);
else y = u,split(l[u],k,x,l[u]);
push_up(u);
}
int Merge(int x,int y){
if(x*y == 0)return x+y;
if(rom[x]<rom[y]){
if(flag[x])push_down(x);
r[x] = Merge(r[x],y);
return push_up(x),x;
}
if(flag[y])push_down(y);
l[y] = Merge(x,l[y]);
return push_up(y),y;
}
void dfs(int u){
if(!u)return;
if(flag[u])push_down(u);
dfs(l[u]);
printf("%d ",val[u]);
dfs(r[u]);
}
int main(){
srand(time(0));
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)root = Merge(root,New(i));
while(m--){
int L,R;
scanf("%d%d",&L,&R);
split(root,L-1,x,y);
split(y,R-L+1,y,z);
flag[y] ^= 1;
root = Merge(Merge(x,y),z);
}
dfs(root);
return 0;
}
和splay很像的操作
Max维护区间最值,lazy区间加,flag区间翻转标记
/*
author:revolIA
submit:;
*/
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+5;
int l[maxn],r[maxn],val[maxn],Size[maxn];
int rom[maxn],cnt;
int flag[maxn],lazy[maxn],Max[maxn];
int root,opt,n,m,a,x,y,z;
void update(int x,int w){
val[x] += w;
lazy[x] += w;
Max[x] += w;
}
void push_up(int x){
Size[x] = 1+Size[l[x]]+Size[r[x]];
Max[x] = val[x];
if(l[x])Max[x] = max(Max[x],Max[l[x]]);
if(r[x])Max[x] = max(Max[x],Max[r[x]]);
}
void push_down(int x){
if(flag[x]){
swap(l[x],r[x]);
flag[l[x]] ^= 1;
flag[r[x]] ^= 1;
flag[x] = 0;
}
if(lazy[x]){
if(l[x])update(l[x],lazy[x]);
if(r[x])update(r[x],lazy[x]);
lazy[x] = 0;
}
}
int New(int x){
Size[++cnt] = 1;
val[cnt] = Max[cnt] = x;
rom[cnt] = rand() << 15 | rand();
lazy[cnt] = flag[cnt] = 0;
return cnt;
}
void split(int u,int k,int &x,int &y){
if(!u){x = y = 0;return;}
push_down(u);
if(Size[l[u]]<k)x = u,split(r[u],k-Size[l[u]]-1,r[u],y);
else y = u,split(l[u],k,x,l[u]);
push_up(u);
}
int Merge(int x,int y){
if(x*y == 0)return x+y;
if(rom[x]<rom[y]){
push_down(x);
r[x] = Merge(r[x],y);
return push_up(x),x;
}
push_down(y);
l[y] = Merge(x,l[y]);
return push_up(y),y;
}
int main(){
srand(time(0));
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)root = Merge(root,New(0));
while(m--){
int K,L,R,V;
scanf("%d%d%d",&K,&L,&R);
split(root,L-1,x,y);
split(y,R-L+1,y,z);
if(K == 1){
scanf("%d",&V);
update(y,V);
}else if(K == 2){
flag[y] ^= 1;
}else{
printf("%d\n",Max[y]);
}
root = Merge(Merge(x,y),z);
}
return 0;
}
果然,学了一个东西看到啥都想去套一下、
/*
author:revolIA
submit:;
*/
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+5;
int l[maxn],r[maxn],val[maxn],Size[maxn];
int rom[maxn],cnt;
ll lazy[maxn],Sum[maxn];
int root,opt,n,m,a,x,y,z;
void update(int x,int w){
val[x] += w;
lazy[x] += w;
Sum[x] += w*Size[x];
}
void push_up(int x){
Size[x] = 1+Size[l[x]]+Size[r[x]];
Sum[x] = val[x];
if(l[x])Sum[x] += Sum[l[x]];
if(r[x])Sum[x] += Sum[r[x]];
}
void push_down(int x){
if(lazy[x]){
if(l[x])update(l[x],lazy[x]);
if(r[x])update(r[x],lazy[x]);
lazy[x] = 0;
}
}
int New(int x){
Size[++cnt] = 1;
val[cnt] = Sum[cnt] = x;
rom[cnt] = rand() << 15 | rand();
lazy[cnt] = 0;
return cnt;
}
void split(int u,int k,int &x,int &y){
if(!u){x = y = 0;return;}
push_down(u);
if(Size[l[u]]<k)x = u,split(r[u],k-Size[l[u]]-1,r[u],y);
else y = u,split(l[u],k,x,l[u]);
push_up(u);
}
int Merge(int x,int y){
if(x*y == 0)return x+y;
if(rom[x]<rom[y]){
push_down(x);
r[x] = Merge(r[x],y);
return push_up(x),x;
}
push_down(y);
l[y] = Merge(x,l[y]);
return push_up(y),y;
}
int main(){
srand(time(0));
scanf("%d%d",&n,&m);
for(int i=1,x;i<=n;i++)scanf("%d",&x),root = Merge(root,New(x));
while(m--){
int K,L,R,V;
scanf("%d%d%d",&K,&L,&R);
split(root,L-1,x,y);
split(y,R-L+1,y,z);
if(K == 1){
scanf("%d",&V);
update(y,V);
}else{
printf("%lld\n",Sum[y]);
}
root = Merge(Merge(x,y),z);
}
return 0;
}