尽人事,听天命。|

Jerrycyx

园龄:2年9个月粉丝:2关注:1

2024-08-09 19:47阅读: 12评论: 0推荐: 0

模板 - 数据结构

并查集

定义 & 初始化

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;
}

压行版本

int ufa[N];
void uInit(){iota(ufa+1,ufa+n+1,1);return;}
int uask(int x){return ufa[x]==x?x:ufa[x]=uask(ufa[x]);}
void umerge(int x,int y){ufa[uask(y)]=uask(x);return;}

单调队列

滑动窗口

head=1,tail=0;
for(int i=1;i<=n;i++)
{
while(head<=tail && i-q[head]+1>k) q[head++]=0;
while(head<=tail && a[q[tail]]>a[i]) q[tail--]=0;
q[++tail]=i;
if(i>=k) res[i-k+1]=q[head];
}

单调栈

for(int i=n;i>=1;i--)
{
while(top && a[sta[top]]<=a[i])
sta[top--]=0;
ans[i]=sta[top];
sta[++top]=i;
}

链表

定义

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;
}

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]);
}
}

树状数组

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;
return;
}
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));
}
}

笛卡尔树

建树

for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
while(top && a[sta[top]]>a[i])
sta[top--]=0;
ls[i]=rs[sta[top]];
rs[sta[top]]=i;
sta[++top]=i;
}

线性基

贪心法

const int B=60;
struct Basis{
long long b[B+5];
Basis(){memset(b,0,sizeof(b));}
void insert(long long x)
{
for(int i=B;i>=0;i--)
if((x>>i)&1)
{
if(b[i]) x^=b[i];
else {b[i]=x;break;}
}
return;
}
long long getmax()
{
long long res=0;
for(int i=B;i>=0;i--)
res=max(res,res^b[i]);
return res;
}
};

高斯消元

int bidx;
void bInit()
{
bidx=1;
#define getbin(x,pos) (((x)>>(pos))&1)
for(int i=B;i>=0;i--)
{
int p=bidx;
while(p<=n && !getbin(a[p],i)) p++;
if(p>n) continue;
swap(a[p],a[bidx]);
for(int j=1;j<=n;j++)
if(j!=bidx && getbin(a[j],i))
a[j]^=a[bidx];
bidx++;
}
#undef getbin
return;
}
posted @   Jerrycyx  阅读(12)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起