模板 - 数据结构

链表

定义

struct Peter{
	int val;
	int nxt,pre;
}node[M];
int idx=0;

初始化

inline void Init() // head:0; tail:n+1
{
	node[0]={0,n+1,0};
	node[n+1]={0,n+1,0};
	return;
}

p 后插入 val

inline void insert(int p,int val)
{
	node[++idx]={val,node[p].nxt,p};
	node[node[p].nxt].pre=idx,node[p].nxt=idx;
	return;
}

删除 p

inline void remove(int p)
{
	node[node[p].nxt].pre=node[p].pre;
	node[node[p].pre].nxt=node[p].nxt;
	return;
}

并查集

定义 & 初始化

int fa[N];
void uInit()
{
	for(int i=1;i<=n;i++)
		fa[i]=i;
	return;
}

查询

int uask(int x)
{
	if(fa[x]==x) return fa[x];
	else return fa[x]=uask(fa[x]);
}

合并

void merge(int x,int y)
{
	fa[ask(y)]=ask(x);
	return;
}

ST 表

\(f_{i,j}\) 表示 \(a_i \sim a_{i+2^j-1}\) 的最大值。

namespace ST_Table{

void Init()
{
	for(int i=2;i<=n;i++)
		lg2[i]=lg2[i>>1]+1;
	for(int k=1;k<=lg2[n];i++)
		for(int i=1;i+(1<<k)-1<=n;i++)
			f[i][k]=max(f[i][k-1],f[i+(1<<k-1)][k-1]);
	return;
}
inline int Query(int l,int r)
{
	int p=lg2[r-l+1];
	return max(f[l][p],f[r-(1<<p)+1][p]);
}

}

TRIE 字典树

void insert(char *st)
{
	int len=strlen(st),p=0;
	for(int i=0;i<len;i++)
	{
		int ch=st[i]-'a'+1;
		if(!trie[p][ch]) trie[p][ch]=++idx;
		p=trie[p][ch];
	}
	end[p]++;
	return;
}
int search(char *st)
{
	int len=strlen(st),p=0;
	for(int i=0;i<len;i++)
	{
		int ch=st[i]-'a'+1;
		p=trie[p][ch];
		if(!p) break;
	}
	return end[p];
}

树状数组

int lowbit(int x){return x&-x;}
void add(int x,int y)
{
	for(;x<=n;x+=lowbit(x))
		c[x]+=y;
	return;
}
int query(int x)
{
	int res=0;
	for(;x;x-=lowbit(x))
		res+=c[x];
	return res;
}

线段树

单点修改

namespace SegmentTree{

struct SegmentTree{
	int l,r;
	int dat;
	int get_mid(){return l+r>>1;}
}tree[N<<2];
void update(int p)
{
	tree[p].dat=tree[p<<1].dat+tree[p<<1|1].dat;
	return;
}
void Build(int l,int r,int p=1)
{
	tree[p].l=l,tree[p].r=r;
	if(l==r)
	{
		treee[p].dat=a[l];
		return;
	}
	int mid=tree[p].get_mid();
	Build(l,mid,p<<1),Build(mid+1,r,p<<1|1);
	update(p);
	return;
}
void add(int x,int y,int p=1)
{
	if(tree[p].l==tree[p].r)
	{
		tree[p].dat+=y;
		return;
	}
	int mid=tree[p].get_mid();
	if(x<=mid) Add(x,y,p<<1);
	else Add(x,y,p<<1|1);
	update(p);
	return;
}
int query(int l,int r,int p=1)
{
	if(l<=tree[p].l&&tree[p].r<=r) return tree[p].dat;
	int mid=tree[p].get_mid(),res=0;
	if(l<=mid) res+=query(l,r,p<<1);
	if(r>mid) res+=query(l,r,p<<1|1);
	return res;
}

}

区间修改(延迟标记)

namespace SegmentTree{

struct SegmentTree{
	int l,r;
	int dat,lazy;
	int get_mid(){return l+r>>1;}
	int get_len(){return r-l+1;}
}tree[N<<2];
void update(int p)
{
	tree[p].dat=tree[p<<1].dat+tree[p<<1|1].dat;
	return;
}
void spread(int p)
{
	if(tree[p].lazy)
	{
		tree[p<<1].dat+=tree[p].lazy*tree[p<<1].get_len();
		tree[p<<1|1].dat+=tree[p].lazy*tree[p<<1|1].get_len();
		tree[p<<1].lazy+=tree[p].lazy;
		tree[p<<1|1].lazy+=tree[p].lazy;
		tree[p].lazy=0;
	}
	return;
}
void Build(int l,int r,int p=1)
{
	tree[p].l=l,tree[p].r=r;
	if(l==r)
	{
		treee[p].dat=a[l];
		return;
	}
	int mid=tree[p].get_mid();
	Build(l,mid,p<<1),Build(mid+1,r,p<<1|1);
	update(p);
	return;
}
void add(int l,int r,int x,int p=1)
{
	if(l<=tree[p].l&&tree[p].r<=r)
	{
		tree[p].dat+=x*tree[p].get_len();
		tree[p].lazy+=x;
	}
	spread(p)
	int mid=tree[p].get_mid();
	if(l<=mid) add(l,r,x,p<<1);
	if(r>mid) add(l,r,x,p<<1|1);
	update(p);
	return;
}
int query(int l,int r,int p=1)
{
	if(l<=tree[p].l&&tree[p].r<=r) return tree[p].dat;
	spread(p);
	int mid=tree[p].get_mid(),res=0;
	if(l<=mid) res+=query(l,r,p<<1);
	if(r>mid) res+=query(l,r,p<<1|1);
	return res;
}

}

平衡树

有旋 Treap

namespace TREAP{

const int INF=1e18;
struct Treap{
	int ls,rs;
	int val,dat;
	int cnt,sz;
}tree[M+N];
#define ls(p) tree[p].ls
#define rs(p) tree[p].rs
int root,idx;

mt19937 engine(chrono::steady_clock::now().time_since_epoch().count());
inline int create(int val)
{
	tree[++idx]={0,0,val,(int)engine(),1,1};
	return idx;
}
inline void update(int p)
{
	tree[p].sz=tree[ls(p)].sz+tree[rs(p)].sz+tree[p].cnt;
	return;
}
inline void zig(int &p) //right rotation 
{
	int q=ls(p);
	tree[p].ls=rs(q);
	tree[q].rs=p;
	p=q;
	update(rs(p)),update(p);
	return;
}
inline void zag(int &p) //left rotation
{
	int q=rs(p);
	tree[p].rs=ls(q);
	tree[q].ls=p;
	p=q;
	update(ls(p)),update(p);
	return;
}

inline void Build()
{
	root=create(-INF);
	tree[root].rs=create(INF);
	tree[rs(root)].dat=tree[root].dat-1;
	update(root);
	return;
}

int get_rank(int val,int p)
{
	if(!p) return 1;
	if(val==tree[p].val) return tree[ls(p)].sz+1;
	if(val<tree[p].val) return get_rank(val,ls(p));
	if(val>tree[p].val) return get_rank(val,rs(p))+tree[ls(p)].sz+tree[p].cnt;
	return -INF; //error
}
int get_value(int rank,int p)
{
	if(!p) return INF; //error
	if(rank<=tree[ls(p)].sz) return get_value(rank,ls(p));
	else if(rank<=tree[ls(p)].sz+tree[p].cnt) return tree[p].val;
	else return get_value(rank-tree[ls(p)].sz-tree[p].cnt,rs(p));
}

void Insert(int val,int &p)
{
	if(!p) {p=create(val); return;}
	if(val==tree[p].val)
	{
		tree[p].cnt++;
		update(p);
		return;
	}
	if(val<tree[p].val)
	{
		Insert(val,ls(p));
		if(tree[p].dat<tree[ls(p)].dat) zig(p);
	}
	if(val>tree[p].val)
	{
		Insert(val,rs(p));
		if(tree[p].dat<tree[rs(p)].dat) zag(p);
	}
	update(p);
	return;
}
void Remove(int val,int &p)
{
	if(!p) return;
	if(val==tree[p].val)
	{
		if(tree[p].cnt>1)
		{
			tree[p].cnt--;
			update(p);
			return;
		}
		else if(ls(p)||rs(p))
		{
			if(!rs(p) || tree[ls(p)].dat>tree[rs(p)].dat)
				zig(p), Remove(val,rs(p));
			else zag(p), Remove(val,ls(p));
			update(p);
		}
		else p=0;
		return;
	}
	if(val<tree[p].val) Remove(val,ls(p));
	if(val>tree[p].val) Remove(val,rs(p));
	update(p);
	return;
}

int get_prev(int val)
{
	int res=0,p=root;
	while(p)
	{
		if(val==tree[p].val)
		{
			if(ls(p)>0)
			{
				p=ls(p);
				while(rs(p)>0) p=rs(p);
				res=p;
			}
			break;
		}
		if(tree[p].val<val && (tree[p].val>tree[res].val || !res)) res=p;
		p=val<tree[p].val?ls(p):rs(p); //WTF!!!!!!!!!!!!!!!!!!
	}
	return tree[res].val;
}
int get_next(int val)
{
	int res=0,p=root;
	while(p)
	{
		if(val==tree[p].val)
		{
			if(rs(p))
			{
				p=rs(p);
				while(ls(p)) p=ls(p);
				res=p;
			}
			break;
		}
		if(tree[p].val>val && (tree[p].val<tree[res].val || !res)) res=p;
		p=val<tree[p].val?ls(p):rs(p);
	}
	return tree[res].val;
}

}

无旋 Treap(FHQ Treap / FHQ 平衡树)

namespace FHQ{

struct Treap{
	int ls,rs;
	int val,dat;
	int sz;
}tree[N+M];
int idx,root;
#define ls(p) tree[p].ls
#define rs(p) tree[p].rs

mt19937 engine(chrono::steady_clock::now().time_since_epoch().count());
inline int create(int val)
{
	tree[++idx]={0,0,val,(int)engine(),1};
	return idx;
}
inline void update(int p)
{
	tree[p].sz=tree[ls(p)].sz+tree[rs(p)].sz+1;
	return;
}

void Split(int val,int p,int &L,int &R)
{
	if(!p) {L=R=0; return;}
	if(tree[p].val<=val)
	{
		L=p;
		Split(val,rs(p),rs(p),R);
		update(L);
	}
	else
	{
		R=p;
		Split(val,ls(p),L,ls(p));
		update(R);
	}
	return;
}
int Merge(int L,int R)
{
	if(!L||!R) return L+R;
	if(tree[L].dat>tree[R].dat)
	{
		rs(L)=Merge(rs(L),R);
		update(L);
		return L;
	}
	else
	{
		ls(R)=Merge(L,ls(R));
		update(R);
		return R;
	}
	return 0;
}

void Insert(int val)
{
	int p=create(val);
	int L,R; Split(val,root,L,R);
	root=Merge(L,Merge(p,R));
	return;
}
void Remove(int val)
{
	int NR,R; Split(val,root,NR,R);
	int L,MID; Split(val-1,NR,L,MID);
	MID=Merge(ls(MID),rs(MID));
	root=Merge(L,Merge(MID,R));
	return;
}

int get_rank(int val)
{
	int L,R; Split(val-1,root,L,R);
	int res=tree[L].sz+1;
	root=Merge(L,R);
	return res;
}
int get_value(int rank)
{
	int p=root;
	while(p)
	{
		int lsz=tree[ls(p)].sz;
		if(rank==lsz+1) return tree[p].val;
		if(rank<=lsz) p=ls(p);
		else rank-=lsz+1,p=rs(p);
	}
	return -1;
}

int get_prev(int val)
{
	return get_value(get_rank(val)-1);
}
int get_next(int val)
{
	return get_value(get_rank(val+1));
}

}
posted @ 2024-08-09 19:47  Jerrycyx  阅读(6)  评论(0编辑  收藏  举报