其他分享
首页 > 其他分享> > 【模板】数据结构

【模板】数据结构

作者:互联网

树剖

戳他

平衡树

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