模板
foreverlasting
2018-07-12 13:40:25
各种板子
最小费用最大流(MCMF):
```
namespace MCMF {
typedef pair<int,int> Pair;
struct E {
int next,to,flow,cost;
E() {}
E(res next,res to,res flow,res cost):next(next),to(to),flow(flow),cost(cost) {}
} edge[M];
int head[N],cnt;
inline void init() {
cnt=-1;
memset(head,-1,sizeof(head));
}
inline void addedge(res u,res v,res x,res y) {
edge[++cnt]=E(head[u],v,x,y),head[u]=cnt;
edge[++cnt]=E(head[v],u,0,-y),head[v]=cnt;
}
int dis[N],flow[N],pre[N],last[N];
bool vis[N];
int q[M],he,ta;
inline int spfa(res S,res T) {
memset(dis,inf,sizeof(dis));
memset(vis,0,sizeof(vis));
memset(flow,inf,sizeof(flow));
he=1,ta=0;
q[++ta]=S;
vis[S]=1,dis[S]=0,pre[T]=-1;
while(he<=ta) {
res now=q[he++];
vis[now]=0;
for(res i=head[now]; ~i; i=edge[i].next) {
res tox=edge[i].to;
if(edge[i].flow>0&&dis[tox]>dis[now]+edge[i].cost) {
dis[tox]=dis[now]+edge[i].cost;
pre[tox]=now;
last[tox]=i;
flow[tox]=min(flow[now],edge[i].flow);
if (!vis[tox])vis[tox]=1,q[++ta]=tox;
}
}
}
return pre[T]!=-1;
}
inline Pair mcmf(res S,res T) {
res maxflow=0,mincost=0;
while(spfa(S,T)) {
res now=T;
maxflow+=flow[T];
mincost+=flow[T]*dis[T];
while (now!=S) {
edge[last[now]].flow-=flow[T];
edge[last[now]^1].flow+=flow[T];
now=pre[now];
}
}
return make_pair(maxflow,mincost);
}
}
```
ST表:
```
#include<bits/stdc++.h>
using namespace std;
#define res register int
#define LL long long
#define inf 0x3f3f3f3f
inline int read() {
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9') {
if(ch=='-')w=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')s=s*10+ch-'0',ch=getchar();
return s*w;
}
inline void write(res w) {
if(w<0)putchar('-'),w=-w;
if(w>9)write(w/10);
putchar(w%10+'0');
}
const int N=1e6+10;
int Max[N][21],Min[N][21];
int n,m;
inline void ST(){
for(res j=1; j<=21; j++)
for(res i=1; i+(1<<j)-1<=n; i++)
Max[i][j]=max(Max[i][j-1],Max[i+(1<<(j-1))][j-1]),Min[i][j]=min(Min[i][j-1],Min[i+(1<<(j-1))][j-1]);
}
inline int QueryMax(res l,res r) {
res k=log2(r-l+1);
return max(Max[l][k],Max[r-(1<<k)+1][k]);
}
inline int QueryMin(res l,res r) {
res k=log2(r-l+1);
return min(Min[l][k],Min[r-(1<<k)+1][k]);
}
int main() {
n=read(),m=read();
for(res i=1; i<=n; i++) Min[i][0]=Max[i][0]=read();
ST();
for(res i=1; i<=m; i++) {
res l=read(),r=read();
write(QueryMax(l,r)),puts("");
}
return 0;
}
```
SAM:
```
namespace SAM {
int siz[N],rt,last,sz;
inline void INIT(){
rt=last=sz=1;
}
struct SAM {
int vis[26],par,len;
inline void init() {
par=len=0;
memset(vis,0,sizeof(vis));
}
}sam[N];
inline void extend(res c) {
res p=last,np=++sz;
sam[np].len=sam[p].len+1;
for(;p&&!sam[p].vis[c];p=sam[p].par)sam[p].vis[c]=np;
if(!p)sam[np].par=rt;
else {
res q=sam[p].vis[c];
if(sam[q].len==sam[p].len+1)sam[np].par=q;
else {
res nq=++sz;
sam[nq]=sam[q];
sam[nq].len=sam[p].len+1;
sam[q].par=sam[np].par=nq;
for(;p&&sam[p].vis[c]==q;p=sam[p].par)sam[p].vis[c]=nq;
}
}
last=np,siz[np]=1;
}
int buc[N],rank[N],ans;
inline void pre() {
for(res i=1;i<=sz;i++)buc[sam[i].len]++;
for(res i=1;i<=sz;i++)buc[i]+=buc[i-1];
for(res i=1;i<=sz;i++)rank[buc[sam[i].len]--]=i;
for(res i=sz;i>=1;i--)siz[sam[rank[i]].par]+=siz[rank[i]];
}
}
```
Splay:
```
inline void rotate(res x){
res y=tr[x].fa,z=tr[y].fa,k=tr[y].son[1]==x,w=tr[x].son[k^1];
if(z)tr[z].son[tr[z].son[1]==y]=x;
tr[x].son[k^1]=y,tr[y].fa=x,tr[x].fa=z;
if(w)tr[w].fa=y;
pushup(y);
}
inline void splay(res x,res w){
while(tr[x].fa!=w){
res y=tr[x].fa,z=tr[y].fa;
if(z!=w)rotate((tr[y].son[0]==x)^(tr[z].son[0]==y)?x:y);
rotate(x);
}
if(!w)rt=x;
pushup(x);
}
```
LCT:
```
namespace LCT {
struct LCT {
int fa,son[2],sz,val,sum;
bool rev;
} tr[N];
int st[N];
inline void pushup(res x) {
res lc=tr[x].son[0],rc=tr[x].son[1];
tr[x].sz=tr[lc].sz+tr[rc].sz+1;
tr[x].sum=tr[lc].sum^tr[rc].sum^tr[x].val;
}
inline void reversed(res x) {
res &lc=tr[x].son[0],&rc=tr[x].son[1];
_swap(lc,rc);
tr[x].rev^=1;
}
inline void pushdown(res x) {
if(tr[x].rev) {
if(tr[x].son[0])reversed(tr[x].son[0]);
if(tr[x].son[1])reversed(tr[x].son[1]);
tr[x].rev=0;
}
}
inline bool nroot(res x) {
return tr[tr[x].fa].son[0]==x||tr[tr[x].fa].son[1]==x;
}
inline void rotate(res x) {
res y=tr[x].fa,z=tr[y].fa,k=tr[y].son[1]==x,w=tr[x].son[k^1];
if(nroot(y))tr[z].son[tr[z].son[1]==y]=x;
tr[x].son[k^1]=y,tr[y].son[k]=w;
if(w)tr[w].fa=y;
tr[y].fa=x,tr[x].fa=z;
pushup(y);
}
inline void splay(res x) {
res i=x,s=0;
st[++s]=x;
while(nroot(i))st[++s]=i=tr[i].fa;
while(s)pushdown(st[s--]);
while(nroot(x)) {
res y=tr[x].fa,z=tr[y].fa;
if(nroot(y))rotate((tr[y].son[0]==x)^(tr[z].son[0]==y)?x:y);
rotate(x);
}
pushup(x);
}
inline void access(res x) {
for(res y=0; x; x=tr[y=x].fa)splay(x),tr[x].son[1]=y,pushup(x);
}
inline void makeroot(res x) {
access(x),splay(x),reversed(x);
}
inline void split(res x,res y) {
makeroot(x),access(y),splay(y);
}
inline int findroot(res x) {
access(x),splay(x);
while(tr[x].son[0])pushdown(x),x=tr[x].son[0];
splay(x);
return x;
}
inline bool link(res x,res y) {
makeroot(x);
if(x==findroot(y))return 0;
tr[x].fa=y;
return 1;
}
inline bool cut(res x,res y) {
makeroot(x);
if(x!=findroot(y)||tr[x].sz>2)return 0;
tr[y].fa=tr[x].son[1]=0;
pushup(x);
return 1;
}
}
```
AC自动机:
```
namespace AC {
#define o
struct AC {
int vis[C],fail,sign,end;
} ac[N];
int cnt;
inline int get(char s) {
return s-'o';
}
inline void clean(res x) {
memset(ac[x].vis,0,sizeof(ac[x].vis));
ac[x].sign=ac[x].fail=0;
}
inline void insert(string s,res sig) {
res len=s.size(),now=0;
for(res i=0; i<len; i++) {
if(!ac[now].vis[get(s[i])])ac[now].vis[get(s[i])]=++cnt,fa[cnt]=now,clean(cnt);
now=ac[now].vis[get(s[i])];
}
ac[now].end=1;
}
int q[N],head,tail;
inline void get_fail() {
head=1,tail=0;
for(res i=0; i<C; i++)if(ac[0].vis[i])ac[ac[0].vis[i]].fail=0,q[++tail]=ac[0].vis[i];
while(head<=tail) {
res u=q[head++];
for(res i=0; i<C; i++)
if(ac[u].vis[i])ac[ac[u].vis[i]].fail=ac[ac[u].fail].vis[i],q[++tail]=ac[u].vis[i];
else ac[u].vis[i]=ac[ac[u].fail].vis[i];
}
}
}
```
网络最大流(DINIC):
```
namespace Dinic{
const int N=1e4+10,M=2e5+10;
struct E{
int next,to,val;
E() {}
E(res next,res to,res val):next(next),to(to),val(val) {}
}edge[M];
int cnt,head[N],S,T,dep[N],cur[N];
inline void init(){
memset(head,-1,sizeof(head));
cnt=-1;
}
inline void addedge(res u,res v,res w){
edge[++cnt]=E(head[u],v,w),head[u]=cnt;
edge[++cnt]=E(head[v],u,0),head[v]=cnt;
}
int q[N],he,ta;
inline bool bfs(){
memset(dep,0,sizeof(dep));
he=1,ta=0;
dep[S]=1;
q[++ta]=S;
while(he<=ta) {
res u=q[he++];
for(res i=head[u];~i;i=edge[i].next){
res tox=edge[i].to;
if(!dep[tox]&&edge[i].val>0)
dep[tox]=dep[u]+1,q[++ta]=tox;
}
}
if(dep[T])return 1;
return 0;
}
inline int dfs(res u,res flow) {
if(u==T)return flow;
for(res& i=cur[u];~i;i=edge[i].next){
res tox=edge[i].to;
if(dep[tox]==dep[u]+1&&edge[i].val){
res f=dfs(tox,_min(flow,edge[i].val));
if(f>0){
edge[i].val-=f;
edge[i^1].val+=f;
return f;
}
}
}
return 0;
}
inline int dinic() {
res ans=0;
while(bfs()) {
memcpy(cur,head,sizeof(cur));
while(int f=dfs(S,inf))ans+=f;
}
return ans;
}
}
```
左偏树:
```
namespace Lheap{
struct Lheap{
int va,son[2],fa,dis;
}lh[N];
int merge(res x,res y){
if(!x||!y)return x+y;
if((lh[x].va>lh[y].va)||(lh[x].va==lh[y].va&&x>y))_swap(x,y);
lh[x].son[1]=merge(lh[x].son[1],y);
lh[lh[x].son[1]].fa=x;
if(lh[lh[x].son[0]].dis<lh[lh[x].son[1]].dis)_swap(lh[x].son[0],lh[x].son[1]);
lh[x].dis=lh[lh[x].son[1]].dis+1;
return x;
}
int find(res x){
return lh[x].fa?find(lh[x].fa):x;
}
inline void pop(res x){
lh[x].va=-1;
lh[lh[x].son[0]].fa=lh[lh[x].son[1]].fa=0;
merge(lh[x].son[0],lh[x].son[1]);
}
}
```
拉格朗日插值:
```
inline int qpow(res x,res y){
res ret=1;
while(y){
if(y&1)ret=1LL*ret*x%kcz;
y>>=1,x=1LL*x*x%kcz;
}
return ret%kcz;
}
inline void add(res &x,const res &y){
x+=y;
x>=kcz?x-=kcz:1;
x<0?x+=kcz:1;
}
inline int calc(const res &x,const res &n){
res tmp=1,ret=0,p=(n&1)?kcz-1:1;
for(res i=1;i<=n;i++)tmp=1LL*tmp*(x-i)%kcz*qpow(i,kcz-2)%kcz;
for(res i=0;i<=n;i++,p=kcz-p)
add(ret,1LL*p*dp[n][i]%kcz*tmp%kcz),tmp=1LL*tmp*(x-i)%kcz*qpow(x-i-1,kcz-2)%kcz*(n-i)%kcz*qpow(i+1,kcz-2)%kcz;
return ret;
}
```
组合数:
```
int inv[N],fac[N];
inline void pre(){
inv[0]=inv[1]=fac[0]=fac[1]=1;
for(res i=2;i<=N-10;i++)fac[i]=(LL)fac[i-1]*i%kcz,inv[i]=(LL)(kcz-kcz/i)*inv[kcz%i]%kcz;
for(res i=2;i<=N-10;i++)inv[i]=(LL)inv[i-1]*inv[i]%kcz;
}
inline int C(res x,res y){
return (LL)fac[x]*inv[y]%kcz*inv[x-y]%kcz;
}
```
虚树:
```
namespace Vir{
inline bool cmp(res x,res y){
return Tree::id[x]<Tree::id[y];
}
struct E{
int next,to;
E() {}
E(res next,res to):next(next),to(to) {}
}edge[N];
int head[N],cnt;
inline void addedge(res u,res v){
edge[++cnt]=E(head[u],v),head[u]=cnt;
}
int st[N],top,H[N],k,tot;
bool vip[N],vis[N];
inline void init(){
cnt=0;
for(res i=1;i<=tot;i++)vis[H[i]]=vip[H[i]]=0,head[H[i]]=-1;
}
inline void Read(){
init();
k=read();
for(res i=1;i<=k;i++)H[i]=read(),vis[H[i]]=vip[H[i]]=1;
}
inline void build(){
Read();
tot=k,sort(H+1,H+tot+1,cmp);
for(res i=1,x;i<tot;i++)if(!vis[x=Tree::get_lca(H[i],H[i+1])])vis[H[++k]=x]=1;
tot=k,sort(H+1,H+tot+1,cmp);
st[top=1]=H[1];
for(res i=2;i<=tot;st[++top]=H[i++]){
while(Tree::id[H[i]]<Tree::id[st[top]]||Tree::low[H[i]]>Tree::low[st[top]])top--;
addedge(st[top],H[i]);
}
}
}
```
边分治:
```
namespace Edtree{
struct E{
LL next,to;
bool tag;
E() {}
E(res next,res to,bool tag):next(next),to(to),tag(tag) {}
}edge[N<<4];
LL head[N],cnt;
inline void init(){
memset(head,-1,sizeof(head));
}
inline void addedge(res u,res v,bool tag){
edge[++cnt]=E(head[u],v,tag),head[u]=cnt;
edge[++cnt]=E(head[v],u,tag),head[v]=cnt;
}
void build(res x,res fax){
res X=x;
bool flag=0;
for(res i=Tree::head[x];~i;i=Tree::edge[i].next){
res tox=Tree::edge[i].to;
if(tox==fax)continue;
if(flag)addedge(x,++n,0),va[n]=va[x],x=n;
addedge(x,tox,1);
build(tox,X);
flag=1;
}
}
bool vis[N];
LL siz[N],rt,w;
void getroot(res x,res fax,res sum){
siz[x]=1;
for(res i=head[x];~i;i=edge[i].next){
res tox=edge[i].to;
if(tox==fax||vis[i>>1])continue;
getroot(tox,x,sum);
siz[x]+=siz[tox];
res K=_max(siz[tox],sum-siz[tox]);
if(K<w)w=K,rt=i;
}
}
```
后缀数组(SA):
```
struct SA{
int str[N];
struct SAM{
int vis[26],par,len,pos;
bool val;
}sam[N<<1];
int cnt,rt,las;
inline void INIT(){
cnt=rt=las=1;
memset(sam,0,sizeof(sam));
}
inline void extend(const res &x,const res &id){
res p=las,np=++cnt;
las=np,sam[np].len=sam[p].len+1,sam[np].pos=id,sam[np].val=1;
for(;p&&!sam[p].vis[x];p=sam[p].par)sam[p].vis[x]=np;
if(!p)sam[np].par=rt;
else {
res q=sam[p].vis[x];
if(sam[q].len==sam[p].len+1)sam[np].par=q;
else {
res nq=++cnt;
memcpy(sam[nq].vis,sam[q].vis,sizeof(sam[nq].vis));
sam[nq].par=sam[q].par,sam[nq].len=sam[p].len+1,sam[nq].pos=sam[q].pos,sam[q].par=sam[np].par=nq;
for(;p&&sam[p].vis[x]==q;p=sam[p].par)sam[p].vis[x]=nq;
}
}
}
int rnk[N],sa[N],hei[N],tot,vis[N<<1][26];
inline void addedge(const res &u,const res &v,const res &c){
vis[u][c]=v;
}
inline void build(){
memset(vis,0,sizeof(vis)),tot=0;
for(res i=2;i<=cnt;i++)addedge(sam[i].par,i,str[sam[i].pos+sam[sam[i].par].len]);
}
void dfs(const res &x){
if(sam[x].val)sa[rnk[sam[x].pos]=++tot]=sam[x].pos;
for(res i=0;i<26;i++)if(vis[x][i])dfs(vis[x][i]);
}
inline void get_hei(){
res k=0;
for(res i=1;i<=n;i++)rnk[sa[i]]=i;
for(res i=1;i<=n;i++){
if(rnk[i]==1)continue;
if(k)k--;
res j=sa[rnk[i]-1];
while(j+k<=n&&i+k<=n&&str[i+k]==str[j+k])k++;
hei[rnk[i]]=k;
}
}
int st[N][21];
inline void ST(){
memset(st,inf,sizeof(st));
for(res i=1;i<=n;i++)st[i][0]=hei[i];
for(res j=1;j<=20;j++)
for(res i=1;i+(1<<j)-1<=n;i++)
st[i][j]=_min(st[i][j-1],st[i+(1<<(j-1))][j-1]);
}
inline int query_min(const res &l,const res &r){
res k=log2(r-l+1);
return _min(st[l][k],st[r-(1<<k)+1][k]);
}
inline int LCP(const res &l,const res &r){
return query_min(_min(rnk[l],rnk[r])+1,_max(rnk[l],rnk[r]));
}
inline void pre(){
INIT();
for(res i=n;i;i--)extend(str[i],i);
build(),dfs(1),get_hei(),ST();
}
}A;
```