FFT
F F T FFT FFT 版本
#include<cmath>
#include<algorithm>
const double pi=acos(-1);
int rev[N*4+5];
struct complex{double x,y;}a[N*4+5],b[N*4+5];
complex operator+(complex a,complex b){a.x+=b.x,a.y+=b.y;return a;}
complex operator-(complex a,complex b){a.x-=b.x,a.y-=b.y;return a;}
complex operator*(complex a,complex b){a.x=a.x*b.x-a.y*b.y;a.y=a.x*b.y+a.y*b.x;return a;}
void fft(complex a[],int n,int dft)
{
for(int i=0;i<n;i++)if(i<rev[i])std::swap(a[i],a[rev[i]]);
for(int len=0;len<n;len<<=1)
{
complex w0=(complex){cos(pi/len),sin(pi/len)*dft;}
for(int i=0;i<n;i+=(len<<1))
{
complex w=(complex){1,0};
for(int j=i;j<i+len;j++)
{
complex x=a[i],y=a[j]*w;
a[i]=x+y,a[j]=x-y;
w=w*w0;
}
}
}if(dft==-1)for(int i=0;i<n;i++)a[i].x/=n;
}
void mul(complex a[],int lena,complex b[],int lenb)
{
int n=lena+lenb-1,s=1,bit=0;while(s<n)s<<=1,bit++1;
for(int i=0;i<s;i++)rev[i]=(rev[i>>1]>>1)|((i&1)<<bit-1);
for(int i=lena;i<s;i++)a[i].x=a[i].y=0;fft(a,s,1);
for(int i=lenb;i<s;i++)b[i].x=b[i].y=0;fft(b,s,1);
for(int i=0;i<s;i++)a[i]=a[i]*b[i];fft(a,s,-1);
}
N T T NTT NTT 版本
#define mo 998244353
int a[N*4+5],b[N*4+5],rev[N*4+5];
int ksm(int a,int p)
{int ans=1;for(;p;p>>=1,a=1ll*a*a%mo_)if(p&1)ans=1ll*ans*a%mo;return ans;}
void swap(int&a,int&b){a^=b,b^=a,a^=b;}
int inc(int a,int b){return a+b>=mo?a+b-mo:a+b;}
void fft(int a[],int n,int dft)
{
for(int i=0;i<n;i++)if(i<rev[i])swap(a[i],a[rev[i]]);
for(int len=1;len<n;len<<=1)
{
int g0=ksm(3,(mo-1)/(len<<1));
if(dft==-1)g0=ksm(g0,mo-2);
for(int i=0;i<len;i+=(len<<1))
{
int g=1;
for(int j=i;j<i+len;j++)
{
int x=a[j],y=1ll*a[j+len]*g;
a[j]=inc(x,y),a[j+len]=inc(x,mo-y);
g=1ll*g*g0%mo;
}
}
}if(dft==-1)
{int inv=ksm(n,mo-2);for(int i=0;i<n;i++)a[i]=1ll*a[i]*inv%mo;}
}
void mul(int a[],int lena,int b[],int lenb)
{
int n=lena+lenb-1,s=1,bit=0;while(s<n)s<<=1,bit++;
for(int i=0;i<s;i++)rev[i]=(rev[i>>1]>>1)|((i&1)<<bit-1);
for(int i=lena;i<s;i++)a[i]=0;fft(a,s,1);
for(int i=lenb;i<s;i++)b[i]=0;fft(b,s,1);
for(int i=0;i<s;i++)a[i]=1ll*a[i]*b[i]%mo;fft(a,s,-1);
}
网络流
最大流
#define min(a,b) (a<b?a:b)
int num=1,d[N+5],head[N+5],t,q[N+5];
struct edge{int to,next,flow;}e[M+5];
void add(int u,int v,int flow)
{
e[++num]=(edge){v,head[u],flow},head[u]=num;
e[++num]=(edge){u,head[v],0},head[v]=num;
}
bool bfs()
{
for(int i=1;i<=t;i++)d[i]=0;q[1]=0;d[0]=1;int l=0,r=1;
while(l<r)
{
int u=q[++l];
for(int i=head[u];i;i=e[i].next)if(e[i].flow)
{
int v=e[i].to;if(d[v])continue;
d[v]=d[u]+1;q[++r]=v;
}
}return d[t];
}
int dfs(int u,int flow)
{
if(u==t)return flow;
int ans=0;bool used=0;
for(int i=head[u];i;i=e[i].next)if(e[i].flow)
{
int v=e[i].to;if(v!=d[u]+1)continue;
int tmp=dfs(v,min(flow,e[i].flow));
if(tmp)
{
b=1;ans+=tmp,flow-=tmp;
e[i].flow-=tmp,e[i^1].flow+=tmp;
if(!flow)return ans;
}
}if(!b)d[u]=-1e9;return ans;
}
int dinic(){int ans=0;while(bfs())ans+=dfs(0,1e9);return ans;}
最大费用流
#define min(a,b) (a<b?a:b)
int num=1,d[N+5],head[N+5],q[N+5],from[N+5],t;bool used[N+5];
int min(int a,int b){return a<b?a:b;}
struct edge{int to,next,flow,cost;}e[M+5];
void add(int u,int v,int flow,int cost)
{
e[++num]=(edge){v,head[u],flow,cost},head[u]=num;
e[++num]=(edge){u,head[v],0,-cost},head[v]=num;
}
bool bfs()
{
for(int i=1;i<=t;i++)d[i]=-1e9;q[1]=0;d[0]=0;int l=0,r=1;
while(l<r)
{
r=l==t?1:l+1;int u=q[l];used[u]=0;
for(int i=head[u];i;i=e[i].next)if(e[i].flow)
{
int v=e[i].to;if(d[v]>=d[u]+e[i].cost)continue;
d[v]=d[u]+e[i].cost;from[v]=i;
if(!used[v])used[v]=1,r=r==t?1:r+1,q[r]=v;
}
}return d[t]>-1e9;
}
int work()
{
int ans=0;
while(bfs())
{
int tmp=0;
for(int i=from[t];i;i=from[e[i^1].to])tmp=min(tmp,e[i].flow);
for(int i=from[t];i;i=from[e[i^1].to])e[i].flow-=tmp,e[i^1].flow+=tmp;
ans+=tmp*d[t];
}return ans;
}
树链剖分
int dfn[N+5],pos[N+5],dep[N+5],tim,fa[N+5],top[N+5],size[N+5],son[N+5];
void dfs1(int u)
{
for(int i=head[u];i;i=e[i].next)
{
int v=e[i].to;if(fa[u]==v)continue;
dep[v]=dep[u]=1;fa[v]=u;dfs1(v);size[u]+=size[v];
if(size[son[u]]<size[v])son[u]=v;
}size[u]++;
}
void dfs2(int u,int rt)
{
dfn[u]=++tim;pos[tim]=u;top[u]=rt;
if(son[u])dfs2(son[u],rt);
for(int i=head[u];i;i=e[i].next)
{int v=e[i].to;if(v==fa[u]||v==son[u])continue;dfs2(v,v);}
}
void swap(int&a,int&b){a^=b,b^=a,a^=b;}
void solve(int x,int y)
{
int fx=top[x],fy=top[y],ans=0;
while(fx!=fy)
{
if(dep[fx]<dep[fy])swap(x,y),swap(fx,fy);
ans+=query(1,1,n,dfn[fa[x]],dfn[x]);
x=fa[fx],fx=top[x];
}if(dep[x]<dep[y])swap(x,y);
ans+=query(1,1,n,dfn[y],dfn[x]);
return ans;
}
LCA
int dep[N+5],log[2*N],st[2*N][25],bit[25];
void dfs(int u,int fa)
{
st[++tim][0]=u;pos[u]=tim;dep[u]=dep[fa]+1;
for(int i=head[u];i;i=e[i].next)
{
int v=e[i].to;if(v==fa)continue;
dfs(v,u);st[++tim][0]=u;
}
}
#define stmin(i,j) (dep[i]<dep[j]?i:j)
void swap(int&a,int&b){a^=b,b^=a,a^=b;}
int getlca(int x,int y)
{
x=pos[x],y=pos[y];if(x>y)swap(x,y);int t=log[y-x+1];
return stmin(st[x][t],st[y-bit[t]+1][t]);
}
void pre()
{
log[0]=-1,bit[0]=1;
for(int i=1;i<=tim;i++)log[i]=log[i>>1]+1;
for(int i=1;bit[i]=bit[i-1]<<1,i<=log[tim];i++)
for(int j=1;j+bit[i]-1<=tim;j++)
st[j][i]=stmin(st[j][i-1],st[j+bit[i-1]][i-1]);
}