模板


目录
  • Dinic
  • KMP
  • 点双连通分量
  • 行列式
  • 后缀数组
  • 后缀自动机
  • 费用流
  • LCT+Splay
  • 扩展卢卡斯
  • trie图
  • FWT
  • KD树
  • 欧拉回路
  • 线性基
  • 强连通分量
  • FFT
  • Manacher
  • KM最优完美匹配

Dinic

#include 
#define MN 100010
#define MM 100010
#define inf 99999999
int fr[MN],ne[MM],v[MM],w[MM],bs=0;
int jl[MN],S,T,N,dl[MN],dy[MN];
bool bk[MN];
void add(int a,int b,int c)
{
	v[bs]=b;
	w[bs]=c;
	ne[bs]=fr[a];
	fr[a]=bs++;
}
void addb(int a,int b,int c)
{
    add(a,b,c);
    add(b,a,0);
}
bool bfs()
{
	for(int i=1;i<=N;i++)
		bk[i]=false,jl[i]=inf;
	bk[S]=true;
	int he=0,ta=1;
	dl[0]=S;jl[S]=0;
	while(he0&&!bk[v[i]])
			{
				bk[v[i]]=true;
				jl[v[i]]=jl[u]+1;
				dl[ta++]=v[i];
			}
		}
	}
	return jl[T]0)
		{
			int rtn=dfs(t,z

KMP

int KMP(char S[200010],char T[200010],int wz[200010],int n,int m)
{
	ne[0]=-1;
	for(int i=1;i<=m;i++)
	{
		int t=ne[i-1];
		while(t!=-1&&T[i-1]!=T[t])
			t=ne[t];
		ne[i]=t+1;
	}
	int a=0,b=0,sl=0;
	while(a<=n)
	{
		if(b==m)
		{
			wz[sl++]=a-m;
			b=ne[b];
		}
		if(b==-1||S[a]==T[b])
			a+=1,b+=1;
		else
			b=ne[b];
	}
	return sl;
}

点双连通分量

void tarjan(int u,int f)
{
	st[tp++]=u;
	dfn[u]=low[u]=++tm;
	for(int i=fr[u];i!=-1;i=ne[i])
	{
		if(v[i]==f)continue;
		if(!dfn[v[i]])
		{
			int la=tp,lb=tb;
			sb[tb++]=i;tarjan(v[i],u);
			if(low[v[i]]>=dfn[u])
			{
				ss+=1;
				for(int j=la;j

行列式

int hangls(int sz[102][102],int n)
{
	int jg=1;
	for(int i=0;i

后缀数组

int sa[30010],x[60010],y[30010],sl[30010],ra[30010],hei[30010];
char zf[30010];
void getsa(int n)
{
	for(int i=0;i=0;i--)
	    sa[--sl[x[i]]]=i;
	int m='z';
	for(int mi=1;mi<=n;mi*=2)
	{
	    int s=0;
	    for(int i=n-mi;i=mi)
				y[s++]=sa[i]-mi;
	    }
	    for(int i=1;i<=m;i++)
			sl[i]=0;
	    for(int i=0;i=0;i--)
			sa[--sl[x[y[i]]]]=y[i];
	    m=1;
	    for(int i=0;i0)
			h-=1;
	    int j=sa[ra[i]-1];
	    while(zf[i+h]==zf[j+h])
			h+=1;
	    hei[ra[i]]=h;
	}
}

后缀自动机

int fa[2000010],trs[2000010][26],len[2000010],sl=1,la=1;
void insert(int c)
{
	int np=++sl,p=la;
	len[np]=len[la]+1,la=np;
	while(p!=0&&trs[p][c]==0)
	{
		trs[p][c]=np;
		p=fa[p];
	}
	if(p==0)
		fa[np]=1;
	else
	{
		int q=trs[p][c];
		if(len[q]==len[p]+1)
			fa[np]=q;
		else
		{
			int nq=++sl;
			len[nq]=len[p]+1;
			fa[nq]=fa[q];
			fa[np]=fa[q]=nq;
			for(int i=0;i<26;i++)
				trs[nq][i]=trs[q][i];
			while(p!=0&&trs[p][c]==q)
			{
				trs[p][c]=nq;
				p=fa[p];
			}
		}
	}
}

费用流

#include 
int fr[1005],ne[10010],v[10010],w[10010],fy[10010],bs=0;
int jl[1005],dl[400010],N,S,T,inf=99999999;
bool bk[1005];
void add(int a,int b,int c,int d)
{
	v[bs]=b;
	w[bs]=c;
	fy[bs]=d;
	ne[bs]=fr[a];
	fr[a]=bs++;
}
void addb(int a,int b,int c,int d)
{
	add(a,b,c,d);
	add(b,a,0,-d);
}
bool spfa()
{
	int he=0,ta=1;
	for(int i=1;i<=N;i++)
	{
		bk[i]=false;
		jl[i]=inf;
	}
	dl[0]=S;jl[S]=0;
	while(he0&&jl[u]+fy[i]

LCT+Splay

#include 
int c1[2010],c2[2010],fa[2010];
int wz[2010],qz[2010];
bool ld[2010];
void pu(int i)
{
	wz[i]=wz[c1[i]];
	if(qz[wz[c2[i]]]>qz[wz[i]])
		wz[i]=wz[c2[i]];
	if(qz[i]>qz[wz[i]])
		wz[i]=i;
}
void pur(int x)
{
	ld[x]=!ld[x];
	int t=c1[x];
	c1[x]=c2[x];
	c2[x]=t;
}
void pd(int x)
{
	if(ld[x])
	{
		if(c1[x]!=0)
			pur(c1[x]);
		if(c2[x]!=0)
			pur(c2[x]);
		ld[x]=false;
	}
}
void zuox(int x)
{
	int t=c2[x];
	c2[x]=c1[t];fa[c1[t]]=x;
	c1[t]=x;fa[t]=fa[x];
	if(x==c1[fa[x]])c1[fa[x]]=t;
	else if(x==c2[fa[x]])c2[fa[x]]=t;
	fa[x]=t;
	pu(x);pu(t);
}
void youx(int x)
{
	int t=c1[x];
	c1[x]=c2[t];fa[c2[t]]=x;
	c2[t]=x;fa[t]=fa[x];
	if(x==c1[fa[x]])c1[fa[x]]=t;
	else if(x==c2[fa[x]])c2[fa[x]]=t;
	fa[x]=t;
	pu(x);pu(t);
}
void rotate(int x)
{
	if(x==c1[fa[x]])
		youx(fa[x]);
	else
		zuox(fa[x]);
}
bool isrt(int x)
{
	return x!=c1[fa[x]]&&x!=c2[fa[x]];
}
void clean(int x)
{
	if(!isrt(x))
		clean(fa[x]);
	pd(x);
}
void splay(int x)
{
	clean(x);
	while(!isrt(x))
	{
		if(isrt(fa[x]))
			rotate(x);
		else
		{
			int f=fa[x];
			if((f==c1[fa[f]])==(x==c1[f]))
			{
				rotate(fa[x]);
				rotate(x);
			}
			else
				rotate(x);
		}
	}
}
void access(int x)
{
	int y=0;
	while(x!=0)
	{
		splay(x);
		c2[x]=y;
		pu(x);
		y=x;x=fa[x];
	}
}
void makert(int x)
{
	access(x);
	splay(x);
	pur(x);
}
int findrt(int x)
{
	access(x);
	splay(x);
	while(c1[x]!=0)
		x=c1[x];
	splay(x);
	return x;
}
void link(int x,int y)
{
	makert(x);
	makert(y);
	fa[x]=y;
}
void cut(int x,int y)
{
	makert(x);
	access(y);
	splay(x);
	c2[x]=fa[y]=0;
}
int getmax(int x,int y)
{
	makert(x);
	access(y);
	splay(x);
	return wz[x];
}

扩展卢卡斯

int qz[30][10010];
void dfs(int n,int &a,int &b,int x,int mi,int bh)
{
	if(n==0)
	{
		a=1;b=0;
		return;
	}
	dfs(n/x,a,b,x,mi,bh);
	b+=n/x;
	a=1ll*a*ksm(qz[bh][mi],n/mi,mi)%mi;
	a=1ll*a*qz[bh][n%mi]%mi;
}
void exgcd(int a,int b,int &x,int &y)
{
	if(b==0)
	{
		x=1;
		y=0;
	}
	else
	{
		exgcd(b,a%b,y,x);
		y-=(a/b)*x;
	}
}
int getws(int n,int x)
{
	int rt=0;
	while(n>0)
	{
		rt+=n/x;
		n/=x;
	}
	return rt;
}
int getz(int n,int m,int x,int mi,int k,int bh)
{
	if(getws(n,x)-getws(m,x)-getws(n-m,x)>=k)
		return 0;
	int a1,b1;dfs(n,a1,b1,x,mi,bh);
	int a2,b2;dfs(n-m,a2,b2,x,mi,bh);
	int a3,b3;dfs(m,a3,b3,x,mi,bh);
	b1-=(b2+b3);
	int x2,y2,x3,y3;
	exgcd(a2,mi,x2,y2);
	exgcd(a3,mi,x3,y3);
	x2=(x2%mi+mi)%mi;
	x3=(x3%mi+mi)%mi;
	a1=1ll*a1*x2%mi*x3%mi;
	return 1ll*a1*ksm(x,b1,mi)%mi;
}
int fj[30],mi[30],xs[30],cs[30],sl=0;
void getcrt(int p)
{
	int tp=p;sl=0;
	for(int i=2;1ll*i*i<=tp;i++)
	{
		if(tp%i==0)
		{
			fj[sl]=i;mi[sl]=1;cs[sl]=0;
			while(tp%i==0)
			{
				tp/=i;
				mi[sl]*=i;
				cs[sl]+=1;
			}
			sl+=1;
		}
	}
	if(tp!=1)
	{
		fj[sl]=mi[sl]=tp;
		cs[sl++]=1;
	}
	for(int i=0;in)
		return 0;
	int jg=0;
	for(int i=0;i

trie图

void bfs()
{
	int he=0,ta=1;
	dl[0]=0;
	while(he

FWT

void fwtor(int sz[132000],int n)
{
    for(int i=2;i<=n;i=(i<<1))
    {
        for(int j=0;j>1);k++)
                sz[j+(i>>1)+k]=(sz[j+(i>>1)+k]+sz[j+k])%md;
        }
    }
}
void ifwtor(int sz[132000],int n)
{
    for(int i=2;i<=n;i=(i<<1))
    {
        for(int j=0;j>1);k++)
                sz[j+(i>>1)+k]=(sz[j+(i>>1)+k]-sz[j+k]+md)%md;
        }
    }
}
void fwtand(int sz[132000],int n)
{
    for(int i=2;i<=n;i=(i<<1))
    {
        for(int j=0;j>1);k++)
                sz[j+k]=(sz[j+k]+sz[j+(i>>1)+k])%md;
        }
    }
}
void ifwtand(int sz[132000],int n)
{
    for(int i=2;i<=n;i=(i<<1))
    {
        for(int j=0;j>1);k++)
                sz[j+k]=(sz[j+k]-sz[j+(i>>1)+k]+md)%md;
        }
    }
}
void fwtxor(int sz[132000],int n)
{
    for(int i=2;i<=n;i=(i<<1))
    {
        for(int j=0;j>1);k++)
            {
                int a=sz[j+k],b=sz[j+(i>>1)+k];
                sz[j+k]=(a+b)%md;
                sz[j+(i>>1)+k]=(a-b+md)%md;
            }
        }
    }
}
void ifwtxor(int sz[132000],int n)
{
    for(int i=2;i<=n;i=(i<<1))
    {
        for(int j=0;j>1);k++)
            {
                int a=sz[j+k],b=sz[j+(i>>1)+k];
                sz[j+k]=1ll*(a+b)*inv%md;
                sz[j+(i>>1)+k]=1ll*(a-b+md)*inv%md;
            }
        }
    }
}

KD树

void update(int x)
{
    if(bk[x])
        zx[x]=inf,wz[x]=-1;
    else
        zx[x]=qz[x],wz[x]=x;
    if(cl[x]!=0&&wz[cl[x]]!=-1&&zx[cl[x]]<=zx[x])
        zx[x]=zx[cl[x]],wz[x]=wz[cl[x]];
    if(cr[x]!=0&&wz[cr[x]]!=-1&&zx[cr[x]]<=zx[x])
        zx[x]=zx[cr[x]],wz[x]=wz[cr[x]];
}
void pur(int x,int y)
{
    if(ld[x]!=-1&&y>=ld[x])
        return;
    ld[x]=y;
    if(qz[x]>y)qz[x]=y;
    if(zx[x]>y)zx[x]=y;
}
void pushdown(int x)
{
    if(ld[x]==-1)return;
    if(cl[x]!=0)pur(cl[x],ld[x]);
    if(cr[x]!=0)pur(cr[x],ld[x]);
    ld[x]=-1;
}
void clean(int x)
{
    if(fa[x]!=0)
        clean(fa[x]);
    pushdown(x);
}
void del(int x)
{
    clean(x);
    bk[x]=true;
    for(int i=x;i!=0;i=fa[i])
        update(i);
}
int buix(SPx sz[70010],int l,int r);
int buiy(SPx sz[70010],int l,int r);
void pushup(int rt)
{
    if(cl[rt]!=0)
    {
        lx[rt]=min(lx[rt],lx[cl[rt]]);rx[rt]=max(rx[rt],rx[cl[rt]]);
        ly[rt]=min(ly[rt],ly[cl[rt]]);ry[rt]=max(ry[rt],ry[cl[rt]]);
        fa[cl[rt]]=rt;
    }
    if(cr[rt]!=0)
    {
        lx[rt]=min(lx[rt],lx[cr[rt]]);rx[rt]=max(rx[rt],rx[cr[rt]]);
        ly[rt]=min(ly[rt],ly[cr[rt]]);ry[rt]=max(ry[rt],ry[cr[rt]]);
        fa[cr[rt]]=rt;
    }
}
bool fugai(int Lx,int Rx,int Ly,int Ry,int lx,int rx,int ly,int ry)
{
    return Lx<=lx&&rx<=Rx&&Ly<=ly&&ry<=Ry;
}
bool fenli(int Lx,int Rx,int Ly,int Ry,int lx,int rx,int ly,int ry)
{
    return Lx>rx||lx>Rx||Ly>ry||ly>Ry;
}
int X[70010],Y[70010];
int buix(SPx sz[70010],int l,int r)
{
    if(l>=r)return 0;
    qsort(sz+l,r-l,sizeof(SPx),cmpx);
    int m=(l+r-1)>>1,rt=sz[m].i;
    lx[rt]=rx[rt]=sz[m].x;
    ly[rt]=ry[rt]=sz[m].y;
    cl[rt]=buiy(sz,l,m);
    cr[rt]=buiy(sz,m+1,r);
    pushup(rt);
    return rt;
}
int buiy(SPx sz[70010],int l,int r)
{
    if(l>=r)return 0;
    qsort(sz+l,r-l,sizeof(SPx),cmpy);
    int m=(l+r-1)>>1,rt=sz[m].i;
    lx[rt]=rx[rt]=sz[m].x;
    ly[rt]=ry[rt]=sz[m].y;
    cl[rt]=buix(sz,l,m);
    cr[rt]=buix(sz,m+1,r);
    pushup(rt);
    return rt;
}
void songc(int i,int Lx,int Rx,int Ly,int Ry,int z)
{
    if(ld[i]!=-1&&z>ld[i])
        return;
    if(fenli(Lx,Rx,Ly,Ry,lx[i],rx[i],ly[i],ry[i]))
        return;
    if(fugai(Lx,Rx,Ly,Ry,lx[i],rx[i],ly[i],ry[i]))
    {
        pur(i,z);
        return;
    }
    pushdown(i);
    if(fugai(Lx,Rx,Ly,Ry,X[i],X[i],Y[i],Y[i]))
    {
        if(qz[i]>z)
            qz[i]=z;
        update(i);
    }
    if(cl[i]!=0)
        songc(cl[i],Lx,Rx,Ly,Ry,z);
    if(cr[i]!=0)
        songc(cr[i],Lx,Rx,Ly,Ry,z);
    update(i);
}

欧拉回路

void dfs(int u)
{
	for(int &i=fr[u];i!=-1;i=ne[i])
	{
		if(bk[i/2])
			continue;
		bk[i/2]=true;
		int a=u,b=v[i];
		dfs(v[i]);
		lu[ls]=a;lv[ls++]=b;
		if(i==-1)break;
	}
}

线性基

    for(int i=0;i<=50;i++)
        zt[i]=-1;
    for(int i=0;i=0;j--)
        {
            if(t&(1ll<=0;i--)
    {
        if(zt[i]!=-1&&(jg^zt[i])>jg)
            jg=(jg^zt[i]);
    }
    printf("%lld",jg);

强连通分量

int dfn[MN],low[MN],tm=0,scc[MN],ss=0,st[MN],tp=0;
void tarjan(int u)
{
	dfn[u]=low[u]=++tm;
	st[tp++]=u;
	for(int i=fr[u];i!=-1;i=ne[i])
	{
		int t=v[i];
		if(!dfn[t])
		{
			tarjan(t);
			low[u]=min(low[u],low[t]);
		}
		else if(!scc[t])
			low[u]=min(low[u],dfn[t]);
	}
	if(dfn[u]==low[u])
	{
		ss+=1;
		while(1)
		{
			scc[st[tp-1]]=ss;
			tp-=1;
			if(st[tp]==u)break;
		}
	}
}

FFT

#include 
#include 
struct cp
{
	double a,b;
	cp(){}
	cp(double A,double B)
	{
		a=A;b=B;
	}
};
cp operator+(cp x,cp y)
{
	return cp(x.a+y.a,x.b+y.b);
}
cp operator-(cp x,cp y)
{
	return cp(x.a-y.a,x.b-y.b);
}
cp operator*(cp x,cp y)
{
	return cp(x.a*y.a-x.b*y.b,x.a*y.b+x.b*y.a);
}
void FFT(cp sz[140000],int n,int lx)
{
	double pi=acos(-1.0);
	for(int i=0,t=0;it)
		{
			cp o=sz[i];
			sz[i]=sz[t];
			sz[t]=o;
		}
		for(int j=(n>>1);(t^=j)>1));
	}
	for(int h=2;h<=n;h=(h<<1))
	{
		cp wn(cos(2*pi*lx/h),sin(2*pi*lx/h));
		for(int i=0;i>1);j++,w=w*wn)
			{
				t=w*sz[j+(h>>1)];
				sz[j+(h>>1)]=sz[j]-t;
				sz[j]=sz[j]+t;
			}
		}
	}
	if(lx==-1)
	{
		for(int i=0;i=n)
		{
			n=i;
			break;
		}
	}
	FFT(sz,n,1);
	FFT(sz,n,-1);
	for(int i=0;i

Manacher

	void man()
	{
		int ma=-1,wz=-1;
		for(int i=0;ima)
					cd[i]=ma-i+1;
			}
			while(i-cd[i]>=0&&i+cd[i]ma)
			{
				ma=i+cd[i]-1;
				wz=i;
			}
		}
	}

KM最优完美匹配

bool dfs(int u)
{
    vg[u]=true;
    for(int i=0;iexg[i])
                exg[i]=sz[i][j];
        }
    }//初始化
    for(int i=0;i