模板 - 数据结构
链表
定义
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));
}
}
本文采用 「CC-BY-NC 4.0」 创作共享协议,转载请注明作者及出处,禁止商业使用。
作者:Jerrycyx,原文链接:https://www.cnblogs.com/jerrycyx/p/18351396