【模板】数据结构
作者:互联网
树剖
平衡树
Splay
点击查看代码
//超级全,啥都有
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5,INF=0x3f3f3f3f;
struct node{
int son[2],cnt,val,tot,fa;
}tr[N];
int co,root;
int read(){
int sum=0,f=1;char a=getchar();
while(a<'0' || a>'9'){if(a=='-') f=-1;a=getchar();}
while(a>='0' && a<='9') sum=sum*10+a-'0',a=getchar();
return sum*f;
}
inline void pushup(int x){
tr[x].tot=tr[tr[x].son[0]].tot+tr[tr[x].son[1]].tot+tr[x].cnt;
}
inline void rotate(int x){
int y=tr[x].fa,z=tr[y].fa,k=(tr[y].son[1]==x);
tr[z].son[tr[z].son[1]==y]=x;
// cout<<"rotate: "<<x<<" "<<z<<" "<<tr[x].val<<" "<<tr[z].val<<endl;
tr[x].fa=z;
tr[y].son[k]=tr[x].son[k^1];
tr[tr[x].son[k^1]].fa=y;
tr[x].son[k^1]=y;
tr[y].fa=x;
pushup(y),pushup(x);
}
void splay(int x,int goal){
while(tr[x].fa!=goal){
int y=tr[x].fa,z=tr[y].fa;
if(z!=goal)
((tr[y].son[1]==x)^(tr[z].son[1]==y))?rotate(x):rotate(y);
rotate(x);
}
if(!goal) root=x;
}
void fi(int x){
int u=root;
if(!u) return;
while(tr[u].son[x>tr[u].val] && tr[u].val!=x)
u=tr[u].son[x>tr[u].val];
splay(u,0);
}
void insert(int x){
int fa=0,u=root;
while(u && tr[u].val!=x){
fa=u;
u=tr[u].son[x>tr[u].val];
}
// cout<<"insert : "<<x<<" "<<u<<" "<<fa<<" "<<tr[u].val<<" "<<tr[fa].val<<endl;
if(u) tr[u].cnt++;
else{
u=++co;
if(fa) tr[fa].son[x>tr[fa].val]=u;
tr[u].fa=fa,tr[u].son[0]=tr[u].son[1]=0;
tr[u].cnt=1,tr[u].tot=1,tr[u].val=x;
}
splay(u,0);
}
int nxt(int x,bool k){
fi(x);
int u=root;
if(tr[u].val>x && k) return u;
if(tr[u].val<x && !k) return u;
u=tr[u].son[k];
while(tr[u].son[k^1]) u=tr[u].son[k^1];
return u;
}
void delet(int x){
int pre=nxt(x,0),suc=nxt(x,1);
splay(pre,0),splay(suc,pre);
int del=tr[suc].son[0];
if(tr[del].cnt>1){
tr[del].cnt--;
splay(del,0);
}
else tr[suc].son[0]=0;
}
int rk(int x){
fi(x);
return tr[tr[root].son[0]].tot+1;
}
int kth(int p,int x){
// cout<<"kth : "<<p<<" "<<tr[p].tot<<" "<<tr[p].val<<" "<<x<<endl;
if(tr[p].tot<x) return 0;
if(tr[tr[p].son[0]].tot>=x) return kth(tr[p].son[0],x);
if(tr[tr[p].son[0]].tot+tr[p].cnt>=x) return tr[p].val;
return kth(tr[p].son[1],x-tr[tr[p].son[0]].tot-tr[p].cnt);
}
int main(){
insert(-INF),insert(INF);
int n=read(),op,x;
while(n--){
op=read(),x=read();
if(op==1) insert(x);
if(op==2) delet(x);
if(op==3) printf("%d\n",rk(x)-1);
if(op==4) printf("%d\n",kth(root,x+1));
if(op==5) printf("%d\n",tr[nxt(x,0)].val);
if(op==6) printf("%d\n",tr[nxt(x,1)].val);
}
return 0;
}
线段树
单点加减,区间询问
模板
#include<bits/stdc++.h>
using namespace std;
#define mid ((l+r)>>1)
const int N=1e5+5;
int tr[N<<2];
void pushup(int node){
tr[node]=tr[node<<1]+tr[node<<1|1];
}
void change(int node,int l,int r,int x,int y){
if(l>x || r<x) return;
if(l==r && l==x){
tr[node]+=y;
return;
}
change(node<<1,l,mid,x,y);
change(node<<1|1,mid+1,r,x,y);
pushup(node);
}
int ask(int node,int l,int r,int be,int en){
if(l>en || r<be) return 0;
if(l>=be && r<=en) return tr[node];
return ask(node<<1,l,mid,be,en)+ask(node<<1|1,mid+1,r,be,en);
}
int main(){
int n,m;
cin>>n>>m;
while(m--){
int op,x,y;
cin>>op>>x>>y;
if(op) cout<<ask(1,1,n,x,y)<<endl;
else change(1,1,n,x,y);
}
return 0;
}
区间加减,区间询问
点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define mid ((l+r)>>1)
#define int long long
const int N=1e6+5;
int tr[N<<2],lz[N<<2],len[N<<2];
int read(){
int sum=0,f=1;char a=getchar();
while(a<'0' || a>'9'){if(a=='-') f=-1;a=getchar();}
while(a>='0' && a<='9') sum=sum*10+a-'0',a=getchar();
return sum*f;
}
void print(int x){
if(x<0) putchar('-'),x=-x;
if(x>9) print(x/10);
putchar(x%10+'0');
}
void pushup(int node){
tr[node]=tr[node<<1]+tr[node<<1|1];
}
void push(int node,int x){
tr[node]+=len[node]*x,lz[node]+=x;
}
void pushdown(int node){
if(lz[node]){
push(node<<1,lz[node]);
push(node<<1|1,lz[node]);
lz[node]=0;
}
}
void build(int node,int l,int r){
len[node]=r-l+1;
if(l==r){
tr[node]=read();
return;
}
build(node<<1,l,mid);
build(node<<1|1,mid+1,r);
pushup(node);
}
void change(int node,int l,int r,int be,int en,int x){
if(l>en || r<be) return;
if(l>=be && r<=en){
push(node,x);
return;
}
pushdown(node);
change(node<<1,l,mid,be,en,x);
change(node<<1|1,mid+1,r,be,en,x);
pushup(node);
}
int ask(int node,int l,int r,int be,int en){
if(l>en || r<be) return 0;
if(l>=be && r<=en) return tr[node];
pushdown(node);
return ask(node<<1,l,mid,be,en)+ask(node<<1|1,mid+1,r,be,en);
}
signed main(){
int n,m;
n=read(),m=read();
build(1,1,n);
while(m--){
int op,x,y,z;
op=read(),x=read(),y=read();
if(op==2) print(ask(1,1,n,x,y)),puts("");
else z=read(),change(1,1,n,x,y,z);
}
return 0;
}
区间加乘,区间询问
点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define mid ((l+r)>>1)
#define int long long
const int N=1e5+5;
int p;
int tr[N<<2],lz_add[N<<2],lz_mul[N<<2],len[N<<2];
int read(){
int sum=0,f=1;char a=getchar();
while(a<'0' || a>'9'){if(a=='-') f=-1;a=getchar();}
while(a>='0' && a<='9') sum=sum*10+a-'0',a=getchar();
return sum*f;
}
void pushup(int node){
tr[node]=(tr[node<<1]%p+tr[node<<1|1]%p)%p;
}
void push_add(int node,int x){
tr[node]+=len[node]*x,tr[node]%=p;
lz_add[node]+=x,lz_add[node]%=p;
}
void push_mul(int node,int x){
tr[node]*=x,tr[node]%=p;
lz_mul[node]*=x,lz_mul[node]%=p;
lz_add[node]*=x,lz_add[node]%=p;
}
void pushdown(int node){
if(lz_mul[node]!=1){
push_mul(node<<1,lz_mul[node]);
push_mul(node<<1|1,lz_mul[node]);
lz_mul[node]=1;
}
if(lz_add[node]){
push_add(node<<1,lz_add[node]);
push_add(node<<1|1,lz_add[node]);
lz_add[node]=0;
}
}
void build(int node,int l,int r){
len[node]=r-l+1;
lz_mul[node]=1;
if(l==r){
tr[node]=read()%p;
return;
}
build(node<<1,l,mid);
build(node<<1|1,mid+1,r);
pushup(node);
}
void change_mul(int node,int l,int r,int be,int en,int x){
if(l>en || r<be) return;
if(l>=be && r<=en){
push_mul(node,x);
return;
}
pushdown(node);
change_mul(node<<1,l,mid,be,en,x);
change_mul(node<<1|1,mid+1,r,be,en,x);
pushup(node);
}
void change_add(int node,int l,int r,int be,int en,int x){
if(l>en || r<be) return;
if(l>=be && r<=en){
push_add(node,x);
return;
}
pushdown(node);
change_add(node<<1,l,mid,be,en,x);
change_add(node<<1|1,mid+1,r,be,en,x);
pushup(node);
}
int ask(int node,int l,int r,int be,int en){
if(l>en || r<be) return 0;
if(l>=be && r<=en) return tr[node]%p;
pushdown(node);
return (ask(node<<1,l,mid,be,en)+ask(node<<1|1,mid+1,r,be,en))%p;
}
signed main(){
int n,m;
n=read(),p=read();
build(1,1,n);
m=read();
while(m--){
int op,x,y,z;
op=read(),x=read(),y=read();
if(op==1) z=read(),change_mul(1,1,n,x,y,z);
if(op==2) z=read(),change_add(1,1,n,x,y,z);
if(op==3) printf("%lld\n",ask(1,1,n,x,y));
}
return 0;
}
扫描线
点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define mid ((l+r)>>1)
const int N=2e5+5;
int ly[N];
struct seg{
int x,y[2];
int val;
}a[N];
int len[N<<4],tr[N<<4],sum[N<<4];
inline int read(){
int sum=0,f=1;char a=getchar();
while(a<'0' || a>'9'){if(a=='-') f=-1;a=getchar();}
while(a>='0' && a<='9') sum=sum*10+a-'0',a=getchar();
return sum*f;
}
bool cmp(seg _,seg __){
return _.x<__.x;
}
void build(int node,int l,int r){
len[node]=ly[r+1]-ly[l];
if(l==r) return;
build(node<<1,l,mid);
build(node<<1|1,mid+1,r);
}
void pushup(int node){
if(sum[node])
tr[node]=len[node];
else
tr[node]=tr[node<<1]+tr[node<<1|1];
}
void change(int node,int l,int r,int be,int en,int x){
if(l>en || r<be) return;
if(l>=be && r<=en){
sum[node]+=x;
pushup(node);
return;
}
change(node<<1,l,mid,be,en,x);
change(node<<1|1,mid+1,r,be,en,x);
pushup(node);
}
signed main(){
int n=read();
for(int i=1;i<=n;++i){
a[i].x=read(),a[i].y[0]=a[i+n].y[0]=ly[i]=read();
a[i+n].x=read(),a[i].y[1]=a[i+n].y[1]=ly[i+n]=read();
a[i].val=1,a[i+n].val=-1;
}
n*=2;
sort(a+1,a+n+1,cmp);
sort(ly+1,ly+n+1);
int co=unique(ly+1,ly+n+1)-ly-1;
ly[co+1]=0x3f3f3f3f;
build(1,1,co);
int ans=0;
for(int i=1;i<n;++i){
int y=lower_bound(ly+1,ly+co+1,a[i].y[0])-ly;
int y1=lower_bound(ly+1,ly+co+1,a[i].y[1])-ly-1;
//cout<<y<<" "<<y1<<endl;
change(1,1,co,y,y1,a[i].val);
ans+=tr[1]*(a[i+1].x-a[i].x);
//cout<<a[i].x<<" "<<a[i].val<<" "<<ans<<endl;
}
printf("%lld",ans);
return 0;
}
树状数组
区间加减,区间询问
点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e6+5;
int t1[N],t2[N];
int n;
int read(){
int sum=0,f=1;char a=getchar();
while(a<'0' || a>'9'){if(a=='-') f=-1;a=getchar();}
while(a>='0' && a<='9') sum=sum*10+a-'0',a=getchar();
return sum*f;
}
void print(int x){
if(x<0) putchar('-'),x=-x;
if(x>9) print(x/10);
putchar(x%10+'0');
}
void add(int x,int y){
for(int i=x;i<=n;i+=(i&-i)) t1[i]+=y;
for(int i=x;i<=n;i+=(i&-i)) t2[i]+=x*y;
}
int ask(int x){
int res=0,tmp=0;
for(int i=x;i;i-=(i&-i)) res+=t1[i];
res*=(x+1);
for(int i=x;i;i-=(i&-i)) tmp+=t2[i];
return res-tmp;
}
signed main(){
int m;
n=read(),m=read();
++n;
for(int i=2;i<=n;++i){
int x=read();
add(i+1,-x),add(i,x);
}
while(m--){
int op,x,y,z;
op=read(),x=read(),y=read();
if(op==2) ++x,++y,print(ask(y)-ask(x-1)),puts("");
else ++y,++x,z=read(),add(y+1,-z),add(x,z);
}
return 0;
}
标签:val,int,tr,son,&&,数据结构,模板,op 来源: https://www.cnblogs.com/yolanda-yxr/p/16634167.html