网络最大流(Dinic)
/*
Luogu name: Symbolize
Luogu uid: 672793
*/
#include<bits/stdc++.h>
#define int long long
#define pii pair<int,int>
#define x first
#define y second
#define rep1(i,l,r) for(register int i=l;i<=r;++i)
#define rep2(i,l,r) for(register int i=l;i>=r;--i)
#define rep3(i,x,y,z) for(register int i=x[y];~i;i=z[i])
#define rep4(i,x) for(auto i:x)
#define debug() puts("----------")
const int N=1e5+10;
const int inf=0x3f3f3f3f3f3f3f3f;
using namespace std;
int n,m,s,t,h[N],e[N<<1],ne[N<<1],w[N<<1],idx,now[N],dep[N];
int read()
{
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return f*x;
}
void add(int x,int y,int z)
{
e[idx]=y;
ne[idx]=h[x];
w[idx]=z;
h[x]=idx++;
return;
}
void Add(int x,int y,int z)
{
add(x,y,z);
add(y,x,0);
return;
}
bool bfs()
{
memset(dep,-1,sizeof dep);
queue<int> q;
q.push(s);
dep[s]=0;
now[s]=h[s];
while(!q.empty())
{
int x=q.front();
q.pop();
rep3(i,h,x,ne)
{
int to=e[i];
if(w[i]&&dep[to]==-1)
{
dep[to]=dep[x]+1;
now[to]=h[to];
q.push(to);
if(to==t) return 1;
}
}
}
return 0;
}
int dfs(int x,int sum)
{
if(x==t) return sum;
int ans=0;
rep3(i,now,x,ne)
{
int to=e[i];
now[x]=i;
if(w[i]&&dep[to]==dep[x]+1)
{
int flow=dfs(to,min(sum,w[i]));
if(!flow) dep[to]=-1;
w[i]-=flow;
w[i^1]+=flow;
ans+=flow;
sum-=flow;
}
if(!sum) break;
}
return ans;
}
int Dinic()
{
int ans=0;
while(bfs()) ans+=dfs(s,inf);
return ans;
}
signed main()
{
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
memset(h,-1,sizeof h);
return 0;
}
网络最大流(HLPP)
/*
Luogu name: Symbolize
Luogu uid: 672793
*/
#include<bits/stdc++.h>
#define int long long
#define pii pair<int,int>
#define x first
#define y second
#define rep1(i,l,r) for(register int i=l;i<=r;++i)
#define rep2(i,l,r) for(register int i=l;i>=r;--i)
#define rep3(i,x,y,z) for(register int i=x[y];~i;i=z[i])
#define rep4(i,x) for(auto i:x)
#define debug() puts("----------")
const int N=1e6+10;
const int inf=0x3f3f3f3f3f3f3f3f;
using namespace std;
int n,m,s,t,e[N],h[N],ne[N],w[N],idx,highh[N],ef[N],gap[N],vis[N];
struct cmp{bool operator()(int a,int b)const{return highh[a]<highh[b];}};
priority_queue<int,vector<int>,cmp> q;
int read()
{
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=(x<<3)+(x<<1)+(ch^48);
ch=getchar();
}
return x*f;
}
void add(int x,int y,int z)
{
e[idx]=y;
ne[idx]=h[x];
w[idx]=z;
h[x]=idx++;
return;
}
void Add(int x,int y,int z)
{
add(x,y,z);
add(y,x,0);
return;
}
bool bfs()
{
queue<int> q;
memset(highh,0x3f,sizeof highh);
highh[t]=0;
q.push(t);
while(!q.empty())
{
int x=q.front();
q.pop();
for(int i=h[x];~i;i=ne[i])
{
int to=e[i];
if(w[i^1]&&highh[to]>highh[x]+1)
{
highh[to]=highh[x]+1;
q.push(to);
}
}
}
if(highh[s]!=inf) return 1;
return 0;
}
void push(int x)
{
rep3(i,h,x,ne)
{
int to=e[i];
if(w[i]&&highh[to]+1==highh[x]&&highh[to]<inf)
{
int d=min(ef[x],w[i]);
w[i]-=d;
w[i^1]+=d;
ef[x]-=d;
ef[to]+=d;
if(to!=s&&to!=t&&!vis[to])
{
q.push(to);
vis[to]=1;
}
if(!ef[x]) break;
}
}
return;
}
void relabel(int x)
{
highh[x]=inf;
rep3(i,h,x,ne)
{
int to=e[i];
if(w[i]&&highh[to]+1<highh[x]) highh[x]=highh[to]+1;
}
return;
}
int HLPP()
{
if(!bfs()) return 0;
highh[s]=n;
memset(gap,0,sizeof gap);
rep1(i,1,n) if(highh[i]<inf) ++gap[highh[i]];
rep3(i,h,s,ne)
{
int to=e[i];
int dist=w[i];
if(dist&&highh[to]<inf)
{
w[i]-=dist;
w[i^1]+=dist;
ef[s]-=dist;
ef[to]+=dist;
if(to!=s&&to!=t&&!vis[to])
{
q.push(to);
vis[to]=1;
}
}
}
while(!q.empty())
{
int x=q.top();
vis[x]=0;
q.pop();
push(x);
if(ef[x])
{
if(!--gap[highh[x]]) rep1(j,1,n) if(j!=s&&j!=t&&highh[j]>highh[x]&&highh[j]<n+1) highh[j]=n+1;
relabel(x);
++gap[highh[x]];
q.push(x);
vis[x]=1;
}
}
return ef[t];
}
signed main()
{
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
memset(h,-1,sizeof h);
return 0;
}
网络最小费用最大流(EK+spfa)
/*
Luogu name: Symbolize
Luogu uid: 672793
*/
#include<bits/stdc++.h>
#define int long long
#define pii pair<int,int>
#define x first
#define y second
#define rep1(i,l,r) for(register int i=l;i<=r;++i)
#define rep2(i,l,r) for(register int i=l;i>=r;--i)
#define rep3(i,x,y,z) for(register int i=x[y];~i;i=z[i])
#define rep4(i,x) for(auto i:x)
#define debug() puts("----------")
const int N=1e5+10;
const int inf=0x3f3f3f3f3f3f3f3f;
using namespace std;
int n,m,s,t,h[N],e[N],ne[N],w[N],c[N],idx,dist[N],now[N],max_flow,min_cost;
bool vis[N];
int read()
{
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return f*x;
}
void add(int x,int y,int z,int v)
{
e[idx]=y;
ne[idx]=h[x];
w[idx]=z;
c[idx]=v;
h[x]=idx++;
return;
}
void Add(int x,int y,int z,int v)
{
add(x,y,z,v);
add(y,x,0,-v);
}
bool spfa()
{
queue<int> q;
memset(dist,inf,sizeof dist);
memcpy(now,h,sizeof h);
q.push(s);
dist[s]=0;
vis[s]=1;
while(!q.empty())
{
int x=q.front();
q.pop();
vis[x]=0;
rep3(i,h,x,ne)
{
int to=e[i];
if(w[i]&&dist[to]>dist[x]+c[i])
{
dist[to]=dist[x]+c[i];
if(!vis[to])
{
q.push(to);
vis[to]=1;
}
}
}
}
if(dist[t]!=inf) return 1;
return 0;
}
int dfs(int x,int sum)
{
if(x==t) return sum;
vis[x]=1;
int res=0;
for(int i=now[x];~i;i=ne[i])
{
int to=e[i];
now[x]=i;
if(!vis[to]&&w[i]&&dist[to]==dist[x]+c[i])
{
int flow=dfs(to,min(sum,w[i]));
if(flow)
{
w[i]-=flow;
w[i^1]+=flow;
res+=flow;
sum-=flow;
min_cost+=flow*c[i];
}
if(!sum) break;
}
}
vis[x]=0;
return res;
}
pii MCMF()
{
while(spfa())
{
int x=dfs(s,inf);
while(x)
{
max_flow+=x;
x=dfs(s,inf);
}
}
return make_pair(max_flow,min_cost);
}
signed main()
{
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
memset(h,-1,sizeof h);
return 0;
}
快速傅里叶变化(FFT)
/*
Luogu name: Symbolize
Luogu uid: 672793
*/
#include<bits/stdc++.h>
#define int long long
#define pii pair<int,int>
#define x first
#define y second
#define rep1(i,l,r) for(register int i=l;i<=r;++i)
#define rep2(i,l,r) for(register int i=l;i>=r;--i)
#define rep3(i,x,y,z) for(register int i=x[y];~i;i=z[i])
#define rep4(i,x) for(auto i:x)
#define debug() puts("----------")
const int N=1e7+10;
const int inf=0x3f3f3f3f3f3f3f3f;
const double pi=acos(-1);
using namespace std;
typedef complex<double> cd;
struct FFT
{
int rev[N];
void fft(cd *f,int n,int key)
{
rep1(i,0,n-1) if(i<rev[i]) swap(f[i],f[rev[i]]);
for(int i=1;i<n;i<<=1)
{
cd wn=exp(cd(0,key*pi/i));
for(int j=0;j<n;j+=(i<<1))
{
cd wnk(1,0);
rep1(k,j,i+j-1)
{
cd x=f[k],y=wnk*f[k+i];
f[k]=x+y;
f[k+i]=x-y;
wnk*=wn;
}
}
}
if(key==-1) rep1(i,0,n) a[i]/=n;
return;
}
int init(int len)
{
int x=0,s=1;
while(s<=n+m) s<<=1,++x;
rep1(i,0,s-1) rev[i]=(rev[i>>1]>>1)|((i&1)<<(x-1));
return s;
}
void convolute(int n,cd *a,int m,cd *b,double *ans)
{
int s=init(n+m);
fft(a,s,1);
fft(b,s,1);
rep1(i,0,s) a[i]*=b[i];
fft(a,s,-1);
rep1(i,0,n+m) ans[i]=a[i].real()+0.5;
return;
}
}fft;
int read()
{
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return f*x;
}
signed main()
{
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
return 0;
}
快速数论变化(NTT)
/*
Luogu name: Symbolize
Luogu uid: 672793
*/
#include<bits/stdc++.h>
#define int long long
#define pii pair<int,int>
#define x first
#define y second
#define rep1(i,l,r) for(register int i=l;i<=r;++i)
#define rep2(i,l,r) for(register int i=l;i>=r;--i)
#define rep3(i,x,y,z) for(register int i=x[y];~i;i=z[i])
#define rep4(i,x) for(auto i:x)
#define debug() puts("----------")
const int N=1e7+10;
const int inf=0x3f3f3f3f3f3f3f3f;
const int pi=acos(-1);
const int mod=998244353;
using namespace std;
int n,f[N],g[N];
int power(int a,int b,int p)
{
int ans=1;
while(b)
{
if(b&1) ans=ans*a%p;
a=a*a%p;
b>>=1;
}
return ans;
}
struct NTT
{
int rev[N];
void ntt(int *f,int n,int type)
{
rep1(i,0,n-1) if(i<rev[i]) swap(f[i],f[rev[i]]);
for(int i=1;i<n;i<<=1)
{
int wn=power((~type)?3:332748118,(mod-1)/(i<<1),mod);
for(int j=0;j<n;j+=(i<<1))
{
int wnk=1;
rep1(k,j,i+j-1)
{
int x=f[k],y=wnk*f[k+i]%mod;
f[k]=(x+y)%mod;
f[k+i]=(x-y+mod)%mod;
wnk=wnk*wn%mod;
}
}
}
if(type==-1)
{
int inv=power(n,mod-2,mod);
rep1(i,0,n-1) f[i]=f[i]*inv%mod;
}
return;
}
int init(int len)
{
int x=0,s=1;
while(s<=len) s<<=1,++x;
rep1(i,0,s-1) rev[i]=(rev[i>>1]>>1)|((i&1)<<(x-1));
return s;
}
void convolute(int n,int *a,int m,int *b,int *ans)
{
int s=init(n+m);
ntt(a,s,1);
ntt(b,s,1);
rep1(i,0,s) a[i]=(a[i]*b[i])%mod;
ntt(a,s,-1);
rep1(i,0,n+m) ans[i]=a[i];
return;
}
void get_inv(int n,int *a,int *ans)
{
if(n==1)
{
ans[0]=power(a[0],mod-2,mod);
return;
}
get_inv((n+1)>>1,a,ans);
int s=init(n+n);
int b[s+10]={};
rep1(i,0,n-1) b[i]=a[i];
ntt(b,s,1);
ntt(ans,s,1);
rep1(i,0,s-1) ans[i]=(2-b[i]*ans[i]%mod+mod)%mod*ans[i]%mod;
ntt(ans,s,-1);
rep1(i,n,s-1) ans[i]=0;
return;
}
void cdq_ntt(int l,int r,int *f,int *g)
{
if(l==r) return;
int mid=l+r>>1;
cdq_ntt(l,mid,f,g);
int n=mid-l,m=r-l-1;
int s=init(n+m);
int a[s+10]={},b[s+10]={};
rep1(i,l,mid) a[i-l]=f[i];
rep1(i,1,r-l) b[i-1]=g[i];
int ans[s+10]={};
convolute(n,a,m,b,ans);
rep1(i,mid+1,r) f[i]=(f[i]+ans[i-l-1])%mod;
cdq_ntt(mid+1,r,f,g);
return;
}
}ntt;
int read()
{
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return f*x;
}
signed main()
{
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
return 0;
}
矩阵快速幂
/*
Luogu name: Symbolize
Luogu uid: 672793
*/
#include<bits/stdc++.h>
#define int long long
#define pii pair<int,int>
#define x first
#define y second
#define rep1(i,l,r) for(register int i=l;i<=r;++i)
#define rep2(i,l,r) for(register int i=l;i>=r;--i)
#define rep3(i,x,y,z) for(register int i=x[y];~i;i=z[i])
#define rep4(i,x) for(auto i:x)
#define debug() puts("----------")
const int N=1e5+10;
const int inf=0x3f3f3f3f3f3f3f3f;
const int mod=1e9+7;
using namespace std;
int read()
{
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return f*x;
}
struct Matrix
{
int n,m,a[3][3];
void addclr(){memset(a,0,sizeof a);}
void mulclr()
{
addclr();
rep1(i,0,n-1) a[i][i]=1;
return;
}
Matrix(const int sn=0,const int sm=0){n=sn,m=sm,addclr();}
void init(const int sn,const int sm){n=sn,m=sm;}
Matrix operator+(const Matrix &now)const
{
Matrix ans(n,m);
rep1(i,0,n-1) rep1(j,0,m-1) ans.a[i][j]=(a[i][j]+now.a[i][j])%mod;
return ans;
}
Matrix operator*(const int k)const
{
Matrix ans(n,m);
rep1(i,0,n-1) rep1(j,0,m-1) ans.a[i][j]=a[i][j]*k%mod;
return ans;
}
Matrix operator*(const Matrix &now)const
{
Matrix ans(n,now.m);
rep1(i,0,n-1) rep1(k,0,m-1) rep1(j,0,now.m-1) ans.a[i][j]=(ans.a[i][j]+a[i][k]*now.a[k][j]%mod)%mod;
return ans;
}
Matrix power(int k)
{
Matrix ans(n,m),base=*this;
ans.mulclr();
while(k)
{
if(k&1) ans=ans*base;
base=base*base;
k>>=1;
}
return ans;
}
};
signed main()
{
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
return 0;
}