[模板集合]

各种模板的集合。
1.手写堆

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
//#include<set>
//#include<bits/stdc++.h>
using namespace std;
int n,x,r;
int t=0;
int hp[1000005];
void pus(int x) {
    int now=++t;
    int tp=now/2;
    hp[now]=x;
    while(now>1) {
        int tp=now/2;
        if(hp[now]<hp[tp]) {
            swap(hp[now],hp[tp]);
            now=tp;
        } else break;
    }
}
void del() {
    hp[1]=hp[t];
    t--;
    int now=1;
    while(2*now<=t) {
        int tp=2*now;
        if(hp[tp]>hp[tp+1]&&tp<t)tp++;
        if(hp[tp]<hp[now]) {
            std::swap(hp[tp],hp[now]);
            now=tp;
        } else break;
    }
}
int main() {
    std::cin>>n;
    for(register int i=1; i<=n; i++) {
        std::cin>>r;
        if(r==1) {
            std::cin>>x;
            pus(x);
        } else if(r==2) {
            std::cout<<hp[1]<<endl;
        } else if(r==3) {
            del();
        }
    }
}

2.spfa判负环(spfa还活着的证据)

#include<cstdio>
#include<iostream>
#include<set>
#include<queue>
#include<cstring>
using namespace std;
const int N = 6005;
int T,head[N],ecnt;
int n,m,s;
int dis[N],cnt[N];
bool vis[N];
struct Edge {
    int nxt,to,val;
} e[N<<2];
void add(int bg,int ed,int val) {
    e[++ecnt].nxt=head[bg],e[ecnt].to=ed,e[ecnt].val=val,head[bg]=ecnt;
}
queue<int>q;
bool spfa() {
    memset(cnt,0,sizeof cnt);
    memset(vis,0,sizeof vis); 
    memset(dis,0x3f,sizeof dis);	
    q.push(s);
    dis[s]=0;
    vis[s]=1;
    while(!q.empty()) {
        int u=q.front();
        q.pop();
        vis[u]=0;
        for(int i=head[u]; i; i=e[i].nxt) {
            int v=e[i].to;
            if(dis[v]>dis[u]+e[i].val) {
                if(!vis[v]) {
                    q.push(v);
                    vis[v]=1;

                }
                dis[v]=dis[u]+e[i].val;
                cnt[v]=cnt[u]+1;
                if(cnt[v]==n)return 0;
            }
        }
    }
    return 1;
}
int main() {
    cin>>T;
    while(T--) {
        scanf("%d%d",&n,&m);
        s=-1;
        ecnt=0;
        memset(head,0,sizeof head);
        int a,b,c;
        for(int i=1; i<=m; i++) {
            scanf("%d%d%d",&a,&b,&c);
            if(c<0) s=a;
            add(a,b,c);
        }
        if(s==-1){
            cout<<"YE5\n";continue;
        }
        if(!spfa())	cout<<"YE5\n";
        else cout<<"N0\n";
    }
}

3.ST表

#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
const int N=1e6+7;
int Max[21][N];
int query(int l,int r){
    int k=log2(r-l+1);
    return max(Max[k][l],Max[k][r-(1<<k)+1]);
}
int n,m;
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) scanf("%d",&Max[0][i]);
    
    for(int j=1;j<=21;j++){
        for(int i=1;i+(1<<j)-1<=n;i++){
            Max[j][i]=max(Max[j-1][i],Max[j-1][i+((1<<j-1))]);
        }
    }
    for(int i=1,l,r;i<=m;i++){
        scanf("%d%d",&l,&r);
        printf("%d\n",query(l,r));
    }
}

4.manacher

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int N=11000007;
char s[N<<1],tp[N];
int p[N<<1],n,ans;
void manacher() {
    int id=0,mx=0;
    for(int i=1;i<n;i++) {
        if(i<mx) p[i]=min(p[id*2-i],p[id]+id-i);
        else p[i]=1;
        while(s[i+p[i]]==s[i-p[i]]) p[i]++;
        if(i+p[i]>mx) mx=i+p[i],id=i;
        ans=max(ans,p[i]);
    }
}
int main() {
    scanf("%s",tp);
    n=strlen(tp);
    s[0]=s[1]=';';
    for(int i=0;i<n;i++) {
        s[i+i+2]=tp[i];
        s[i+i+3]=';';
    }
    n=n+n+2;
    s[n]=' ';
    manacher();
    cout<<ans-1;
    return 0;
}

5.EXCRT

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int N=1e5+5;
typedef long long ll;
ll tor(ll d,ll z,ll m) {
    long long res=0;
    while(z) {
        if(z&1) res=(res+d)%m;
        d=(d+d)%m;
        z>>=1;
    }
    return res;
}
ll exgcd(ll &x,ll &y,ll a,ll b) {
    if(!b) {
        x=1,y=0;
        return a;
    }
    ll g=exgcd(x,y,b,a%b);
    ll t=x;
    x=y;
    y=t-a/b*y;
    return g;
}
int n;
ll ai[N],bi[N];
void excrt() {
    ll x,y,k,z,h;
    ll M=ai[1],ans=bi[1];
    for(int i=2;i<=n;i++) {
        ll a=M,b=ai[i],c=(bi[i]-ans%b+b)%b;
        ll g=exgcd(x,y,a,b);
        ll newb=b/g;
        if(c%g!=0) {cout<<-1;return;}
        x=tor(x,c/g,newb);
        ans+=x*M;
        M*=newb;
        ans=(ans%M+M)%M;
    }
    cout<<(ans+M)%M;
}
int main() {
    scanf("%d",&n);	
    for(int i=1;i<=n;i++) scanf("%lld%lld",&ai[i],&bi[i]);
    excrt();
    return 0;
}

6.线性基

#include <cstdio>
long long base[70],n;
void insert(long long x){
    for(int i=60;~i;i--){
        if(x&(1ll<<i)){
        if(!base[i]) {base[i]=x;return;}
        x=x^base[i];}
    }
}
long long query(long long x){
    for(int i=60;~i;i--){
        if((x^base[i])>x)x^=base[i];
    }
    return x;
}
int main(){
    scanf("%d",&n);
    for(long long i=1,a;i<=n;i++) scanf("%lld",&a),insert(a);
    printf("%lld",query(0));
}

7.逆元
https://www.cnblogs.com/sdfzhsz/p/9797175.html
8.后缀排序

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int N=1000005;
int sa[N],rk[N],x[N],y[N],tot,n,m,c[N];
char s[N];
void SA() {
    for(int i=1;i<=n;i++) x[i]=s[i];
    for(int i=1;i<=n;i++) c[x[i]]++;
    for(int i=2;i<=m;i++) c[i]+=c[i-1];
    for(int i=n;i;i--) sa[c[x[i]]--]=i;
    for(int k=1;k<=n;k<<=1) {
        tot=0;
        for(int j=n-k+1;j<=n;j++) y[++tot]=j;
        for(int j=1;j<=n;j++) if(sa[j]>k) y[++tot]=sa[j]-k;
        memset(c,0,sizeof (int)*(m+1));
        for(int i=1;i<=n;i++) c[x[i]]++;
        for(int i=2;i<=m;i++) c[i]+=c[i-1];
        for(int i=n;i;i--) sa[c[x[y[i]]]--]=y[i],y[i]=0;
        swap(x,y);
        x[sa[1]]=1;tot=1;
        for(int i=2;i<=n;i++) {
            x[sa[i]]=(y[sa[i]]==y[sa[i-1]]&&y[sa[i]+k]==y[sa[i-1]+k])?tot:++tot;
        }
        m=tot;
    }
    for(int i=1;i<=n;i++) printf("%d ",sa[i]);
    return;
}	
int main() {
    scanf("%s",s+1);
    n=strlen(s+1);
    m='z';
    SA();
    return 0;
}

9.EXBSGS

#include <cstdio>
#include <cmath>
#include <map>
std::map<int,int> mp;
int a,b,c;
int exgcd( long a, long b, long &x, long &y) {
    if(!b) {
        x=1,y=0;
        return a;
    }
    long  ans=exgcd(b,a%b,x,y),t=x;
    x=y,y=t-a/b*y;
    return ans;
}
long  gcd( long a, long b) {
    return b?gcd(b,a%b):a;
}
long  ksm( long b, long z, long p) {
    long  res=1;
    while(z) {
        if(z&1) res*=b,res%=p;
        b*=b,b%=p;
        z>>=1;
    }
    return res;
}
long  EXBSGS( long a, long b, long p) {
    a%=p,b%=p;
    if(b==1)return 0;
    int cnt=0,d=1;
    for(int g=gcd(a,p); g!=1; g=gcd(a,p)) {
        if(b%g) return -1;
        p/=g,b/=g;
        d=1ll*d*a/g%p;
        ++cnt;
        if(b==d) return cnt;
    }
    mp.clear();
    int m=ceil(sqrt(p)),t=b;
    for(int i=0; i<m; i++) {
        mp[t]=i;
        t=1ll*t*a%p;
    }
    int g=ksm(a,m,p);
    t=1ll*d*g%p;
    for(int i=1; i<=m+1; i++) {
        if(mp.count(t)) 
        return cnt+i*m-mp[t];
        t=1ll*t*g%p;
    }
    return -1;
}
int main() {
    int a,b,p,ans;
    while(~scanf("%d%d%d",&a,&p,&b)) {
        if(!a&&!b&&!p)return 0;
        if(p==1) {
            puts("0");
            continue;
        }
        ans=EXBSGS(a,b,p);
        if(ans==-1) puts("No Solution");
        else  printf("%d\n",ans);
    }
}

10.杜教筛筛phi和miu

#include <iostream>
#include <cstdio>
#include <map>
using namespace std;
typedef long long ll;
const int N=7000000;
int n;
map<int,ll>ph,mu;
int prime[N>>3],tot;ll phi[N],miu[N];
bool vis[N];
void init() {
    miu[1]=phi[1]=1;
    for(int i=2;i<=N-5;i++) {
        if(!vis[i]) prime[++tot]=i,miu[i]=-1,phi[i]=i-1;
        for(int j=1;j<=tot&&prime[j]*i<=N-5;j++) {
            vis[i*prime[j]]=1;
            if(i%prime[j]==0) {phi[i*prime[j]]=phi[i]*prime[j];break;}
            phi[i*prime[j]]=phi[i]*phi[prime[j]];miu[i*prime[j]]=-miu[i];
        }
    }
    for(int i=1;i<=N-5;i++) phi[i]+=phi[i-1],miu[i]+=miu[i-1];
}
ll solvephi(int x) {
    if(x<=N-5) return phi[x];
    if(ph.count(x)) return ph[x];
    ll ans=1ll*x*(x+1)/2;
    for(int i=2,nxti;i<=x;i=nxti) {
        nxti=x/(x/i)+1;
        ans-=(nxti-i)*solvephi(x/i);
    }
    return ph[x]=ans;
}
ll solvemiu(int x) {
    if(x<=N-5) return miu[x];
    if(mu.count(x)) return mu[x];
    ll ans=1;
    for(int i=2,nxti;i<=x;i=nxti) {
        nxti=x/(x/i)+1;
        ans-=(nxti-i)*solvemiu(x/i);
    }
    return mu[x]=ans;
}
int T;
int main() {
    init();
    cin>>T;
    while(T--){
    cin>>n;
    cout<<solvephi(n)<<' '<<solvemiu(n)<<endl;
    }
}

11.树剖+线段树

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<stack>
#include<algorithm>
#include<cstdlib>
#define int long long
using namespace std;
const int N=400005;
int n,m,r,p,a[N],head[N],ecnt,siz[N],fa[N],dep[N],son[N],dfn1[N],dfn2[N],top[N],ncnt,rnk[N]; 
struct Segtree {
    int sum,lazy,l,r;
} seg[N<<2];
struct Edge {
    int to,nxt;
} e[N<<1];
void pushup(int x) {
    seg[x].sum=seg[x<<1].sum+seg[x<<1|1].sum;
    seg[x].sum%=p;
}
void add(int bg,int ed){
    e[++ecnt].nxt=head[bg];
    e[ecnt].to=ed;
    head[bg]=ecnt;
}
void build(int L,int R,int x) {
    seg[x].l=L,seg[x].r=R;
    if(L==R) {
        seg[x].sum=a[rnk[L]];
        return;
    }
    int mid=(L+R)>>1;
    build(L,mid,x<<1);
    build(mid+1,R,x<<1|1);
    pushup(x);
}

void pushdown(int x) {
    if(seg[x].lazy) {
        if(seg[x].l!=seg[x].r) {
            seg[x<<1].sum+=seg[x].lazy*(seg[x<<1].r-seg[x<<1].l+1);
            seg[x<<1].sum%=p;
            seg[x<<1|1].sum+=(seg[x].lazy)*(seg[x<<1|1].r-seg[x<<1|1].l+1);
            seg[x<<1|1].sum%=p;
            seg[x<<1].lazy+=seg[x].lazy;
            seg[x<<1].lazy%=p;
            seg[x<<1|1].lazy+=seg[x].lazy;
            seg[x<<1|1].lazy%=p;
        }
        seg[x].lazy=0;
    }
}
void update(int L,int R,int x,int c) {
    if(R<seg[x].l||L>seg[x].r)return;
    if(L<=seg[x].l&&seg[x].r<=R) {
        seg[x].lazy+=c;
        seg[x].sum+=(seg[x].r-seg[x].l+1)*c;
        seg[x].sum%=p;
        return;
    }
    pushdown(x);
    update(L,R,x<<1,c);
    update(L,R,x<<1|1,c);
    pushup(x);
}
int query(int L,int R,int x){
    if(L>seg[x].r||R<seg[x].l)return 0;
    if(L<=seg[x].l&&seg[x].r<=R){
        return seg[x].sum%p;
    }
    pushdown(x);
    return (query(L,R,x<<1)%p+query(L,R,x<<1|1)%p)%p;
}
void dfs1(int x){
    siz[x]=1;
    for(int i=head[x];i;i=e[i].nxt){
        int v=e[i].to;
        if(fa[x]==v) continue;
        fa[v]=x;
        dep[v]=dep[x]+1;
        dfs1(v);
        siz[x]+=siz[v];
        if(siz[v]>siz[son[x]]) son[x]=v;
    }
}
void dfs2(int x,int qtop){
    top[x]=qtop;dfn1[x]=++ncnt;
    rnk[dfn1[x]]=x;
    if(son[x]) dfs2(son[x],qtop);
    for(int i=head[x];i;i=e[i].nxt){
        int v=e[i].to;
        if(v==fa[x]||v==son[x]) continue;
        dfs2(v,v);
    }
    dfn2[x]=ncnt;
}
void add_v(int x,int y,int z){
    int f1=top[x],f2=top[y];
    while(f1!=f2){
        if(dep[f1]<dep[f2]) swap(f1,f2),swap(x,y);
        update(dfn1[f1],dfn1[x],1,z);
        x=fa[f1],f1=top[x];
    }
    if(dep[x]>dep[y]) update(dfn1[y],dfn1[x],1,z);
    else update(dfn1[x],dfn1[y],1,z);
}
int query_path(int x,int y){
    int f1=top[x],f2=top[y],ans=0;
    while(f1!=f2){
        if(dep[f1]<dep[f2]) swap(f1,f2),swap(x,y);
        ans+=query(dfn1[f1],dfn1[x],1);
        ans%=p;
        x=fa[f1],f1=top[x];
    }
    if(dep[x]>dep[y]) ans+=query(dfn1[y],dfn1[x],1);
    else ans+=query(dfn1[x],dfn1[y],1)%p;
    return ans%p;
}
signed main() {
    cin>>n>>m>>r>>p;
    int u,v,b,c;
    for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
    for(int i=1;i<n;i++){
        scanf("%lld%lld",&u,&v);
        add(u,v);
        add(v,u);
    }
    dfs1(r);
    dfs2(r,r);
    build(1,n,1);
    for(int i=1;i<=m;i++){
        scanf("%lld",&u);
        switch (u){
            case 1:scanf("%lld%lld%lld",&c,&b,&v);add_v(c,b,v);break;
            case 2:scanf("%lld%lld",&c,&b);printf("%lld\n",query_path(c,b));break;
            case 3:scanf("%lld%lld",&b,&c);update(dfn1[b],dfn2[b],1,c);break;
            case 4:scanf("%lld",&b);printf("%lld\n",query(dfn1[b],dfn2[b],1));break;
        }
    }
    return 0;
}

12.树状数组

void add(int x,int y) {
    for(; x<=n; x+=x&-x) {
        f[x]+=y;
    }
}
int query(int x) {
    int sum=0;
    for(; x; x-=x&-x) {
        sum+=f[x];
    }
    return sum;
}

13.Treap

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <ctime>
using namespace std;
const int N=100005;
int ch[N][2],fa[N],siz[N],cnt[N],val[N],prio[N],rt,tot,ans,n;
inline void pushup(int x){siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+cnt[x];}
bool is_right(int x) {return x==ch[fa[x]][1];}
inline void rotate(int &x,int tag) {
    int y=ch[x][tag^1];
    ch[x][tag^1]=ch[y][tag];
    ch[y][tag]=x;
    siz[y]=siz[x];
    pushup(x);
    x=y;
}
void insert(int &x,int k) {
 	if(x==0) {x=++tot;val[x]=k,prio[x]=rand(),siz[x]=cnt[x]=1;return;}
 	siz[x]++;
 	if(k<val[x]) {insert(ch[x][0],k);if(prio[ch[x][0]]<prio[x]) rotate(x,1);}
 	else if(k>val[x]) {insert(ch[x][1],k);if(prio[ch[x][1]]<prio[x]) rotate(x,0);}
 	else if(k==val[x]) cnt[x]++;
}
void del(int &x,int k) {
    if(x==0) return;
    if(val[x]==k) {
        if(cnt[x]>1) {cnt[x]--,siz[x]--;return;}
        if(ch[x][0]==0||ch[x][1]==0) {x=ch[x][0]+ch[x][1];return;}
        if(prio[ch[x][0]]<prio[ch[x][1]]) rotate(x,1),del(x,k);
        else rotate(x,0),del(x,k);
        return;
    }
    if(val[x]<k) {
        siz[x]--;
        del(ch[x][1],k);
    }
    else if(val[x]>k) {
        siz[x]--;
        del(ch[x][0],k);
    }
    pushup(x);
}
int rnk(int x,int k) {
    if(x==0) return 0;
    if(val[x]==k) return siz[ch[x][0]]+1;
    if(val[x]<k) return rnk(ch[x][1],k)+siz[ch[x][0]]+cnt[x];
    if(val[x]>k) return rnk(ch[x][0],k);
}
int getval(int x,int k) {
    if(x==0) return 0;
    if(k<=siz[ch[x][0]]) return getval(ch[x][0],k);
    if(siz[ch[x][0]]+cnt[x]<k) return getval(ch[x][1],k-siz[ch[x][0]]-cnt[x]);
    return val[x];
}
void pre(int x,int k) {
    if(!x) return;
    if(val[x]<k) ans=x,pre(ch[x][1],k);
    else pre(ch[x][0],k);
}
void nxt(int x,int k) {
    if(!x) return;
    if(val[x]>k) ans=x,nxt(ch[x][0],k);
    else nxt(ch[x][1],k);
}
int main() {
    scanf("%d",&n);
    srand(19260817);
    int opt,x;
    for(int i=1;i<=n;i++) {
        scanf("%d%d",&opt,&x);
        if(opt==1)insert(rt,x);
        if(opt==2)del(rt,x);
        if(opt==3)printf("%d\n",rnk(rt,x));
        if(opt==4)printf("%d\n",getval(rt,x));
        if(opt==5)pre(rt,x),printf("%d\n",val[ans]);
        if(opt==6)nxt(rt,x),printf("%d\n",val[ans]);
        
    }
}

14.Splay

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
const int N=100005;
int n,m,a[N];
int val[N],ch[N][2],fa[N],siz[N],rt,tot;
bool rev[N];
inline void pushup(int x) {siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+1;}
int build(int x,int l,int r) {
    if(l>r) return 0;
    int mid=l+r>>1,now=++tot;
    val[now]=a[mid],fa[now]=x;//siz[now]=1;
    ch[now][0]=build(now,l,mid-1);
    ch[now][1]=build(now,mid+1,r);
    pushup(now);
    return now;
}
inline void pushdown(int x) {
    if(!rev[x]) return;
    swap(ch[x][0],ch[x][1]);
    rev[ch[x][0]]^=1;rev[ch[x][1]]^=1;
    rev[x]=0;
}
inline void rotate(int x) {
    int f=fa[x],ff=fa[f];
    bool tag=x==ch[fa[x]][1];
    pushdown(f),pushdown(x);
    ch[f][tag]=ch[x][tag^1];
    fa[ch[f][tag]]=f;
    fa[f]=x;
    fa[x]=ff;
    ch[x][tag^1]=f;
    if(ff) ch[ff][f==ch[ff][1]]=x;
    pushup(f);
    pushup(x);
}
inline void splay(int x,int tar) {
    for(int f;(f=fa[x])!=tar;rotate(x)) if(fa[f]!=tar)rotate((x==ch[fa[x]][0])==(f==ch[fa[f]][0])?f:x);
    if(!tar)
    rt=x;
}
inline int getval(int x) {
    int now=rt;
    while(1) {
        pushdown(now);
        if(x<=siz[ch[now][0]]) now=ch[now][0];
        else {
            x-=siz[ch[now][0]]+1;
            if(!x) return now;
            now=ch[now][1];
        }
    }
}
void print(int x) {
    pushdown(x);
    if(ch[x][0]) print(ch[x][0]);
    if(abs(val[x])!=0x3f3f3f3f) printf("%d ",val[x]);
    if(ch[x][1])print(ch[x][1]);
}
int main() {
    scanf("%d%d",&n,&m);
    a[1]=-0x3f3f3f3f,a[n+2]=0x3f3f3f3f;
    for(int i=1;i<=n;i++) a[i+1]=i;
    rt=build(0,1,n+2);int l,r;
    while(m--) {
        scanf("%d%d",&l,&r);
        l=getval(l),r=getval(r+2);
        splay(l,0);
        splay(r,l);
        rev[ch[ch[rt][1]][0]]^=1;
    }
    print(rt);
}

15.Dinic

//Writer:jr HSZ;%%%GhostCai
#include<bits/stdc++.h>
#define int long long
#define reg register int
#define inf 0x7fffffff
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*10+ch-'0',ch=getchar();
    return x*f;
}
struct Edge {
    int to,nxt,val;
} e[2000005];
int n,m,s,t,mx;
int mxflow;
int cur[20005];
int head[20005],cnt=1;

void add(int bg,int ed,int val) {
    e[++cnt].to=ed;
    e[cnt].nxt=head[bg];
    e[cnt].val=val;
    head[bg]=cnt;
}
int h[20005];
queue<int>q;
bool bfs() {
    memset(h,-1,sizeof h);
    q.push(s);
    h[s]=0;
    while(!q.empty()) {
        int x=q.front();
        q.pop();
        for(int i=head[x]; i; i=e[i].nxt) {
            if(e[i].val&&h[e[i].to]==-1) {
                h[e[i].to]=h[x]+1;
                q.push(e[i].to);
            }
        }
    }
    return h[t]!=-1;
}
int dfs(int x,int f) {
    if(x==t)return f;
    int tp,used=0;
    for(int i=cur[x]; i; i=e[i].nxt) {
        if(e[i].val&&h[e[i].to]==h[x]+1) {
            tp=dfs(e[i].to,min(e[i].val,f-used));
            e[i].val-=tp;
            if(e[i].val)cur[x]=i;
            e[i^1].val+=tp;
            used+=tp;
            if(used==f)return f;
        }
    }
    if(!used)h[x]=-1;
    return used;
}
void dinic() {
    while(bfs()) {
        memcpy(cur,head,sizeof head);
        mxflow+=dfs(s,inf);
    }
}
int x,y,v;
signed main() {
n=read();m=read();s=read();t=read();
    for(int i=1; i<=m; i++) {
        x=read();y=read();v=read();
        add(x,y,v);
        add(y,x,0);
    }
    dinic();
    cout<<mxflow;
    return 0;
}

16.高斯消元

//Writer : Hsz %WJMZBMR%tourist%hzwer
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#include<stack>
#include<vector>
#include<cstdlib>
#include<algorithm>
#define LL long long
using namespace std;
int n,w[105];
const double eps=1e-8;
double a[105][105],b[105],v[105];
void gauss(){
    for(int i=1;i<=n;i++)
    {
        int p=0;
        double mx=0;
        for(int j=1;j<=n;j++) {
            if(fabs(a[i][j])-eps>mx) mx=fabs(a[i][j]),p=j; 
        }
        if(!p) {
            printf("No Solution");
            return;  
        }
        w[i]=p;
        for(int j=1;j<=n;j++)
        {
            if(i!=j){
                double tt=a[j][p]/a[i][p];
                for(int k=1;k<=n+1;k++)
                {
                    a[j][k]-=a[i][k]*tt;
                }
            }
        }
    }
    for(int i=1;i<=n;i++) v[w[i]]=a[i][n+1]/a[i][w[i]];
    for(int i=1;i<=n;i++) printf("%.2lf\n" ,v[i]);
}
int main() {
    cin>>n;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n+1;j++)
            scanf("%lf",&a[i][j]);
//		scanf("%lf",&b[i]);
    }
    gauss();
    return 0;
}

17.Lucas

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int N=1e7+7;
int T,n,m,mod;
long long fac[N];
void ready(int x)
{
    fac[0]=1;
    for(int i=1;i<=x;i++) fac[i]=fac[i-1]*i%mod;
}
long long ksm(long long d,long long z)
{
    long long res=1;
    d%=mod;
    while(z)
    {
        if(z&1) res*=d,res%=mod;
        d*=d;
        d%=mod;
        z>>=1;
    }
    return res%mod;
}
long long fermat(long long m,long long n)
{
    if(n<m)return 0;
    return fac[n]*ksm(fac[m],mod-2)%mod*ksm(fac[n-m],mod-2)%mod;
}
long long lucas(int m,int n)
{
    long long ans=1;
    while(n and m and ans)
    {
        ans=(ans*(fermat(m%mod,n%mod)))%mod;
        n/=mod;
        m/=mod;
    }
    return ans;
}
int main()
{
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d%d",&n,&m,&mod);
        ready(n+m);
        printf("%lld\n",lucas(n,m+n));
    }
}

18.左偏树

//Writer : Hsz %WJMZBMR%tourist%hzwer
#include <iostream>
#include <cstring>
#include <cstdio>
int in(){
    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-'0';ch=getchar();}
    return x*f;
}
void out(int x)
{
    int a[25],wei=0;
    if(x<0) putchar('-'),x=-x;
    for(;x;x/=10) a[++wei]=x%10;
    if(wei==0){ puts("0"); return;}
    for(int j=wei;j>=1;--j) putchar('0'+a[j]);
    putchar('\n');
}
void swap(int &x,int &y){int t=x;x=y,y=t;}
const size_t N=100005;
int n,m,val[N],ch[N][2],fa[N],dis[N];
int merge(int x,int y){
    if(!x||!y)return x+y;
    if(val[x]>val[y]||(val[x]==val[y]&&x>y)){swap(x,y);}
    ch[x][1]=merge(ch[x][1],y);
    fa[ch[x][1]]=x;
    if(dis[ch[x][0]]<dis[ch[x][1]])swap(ch[x][0],ch[x][1]);
    dis[x]=dis[ch[x][1]]+1;
    return x;
}
int find(int x){while(fa[x]) x=fa[x];return x;}
void pop(int x){val[x]=-1;fa[ch[x][0]]=fa[ch[x][1]]=0;merge(ch[x][0],ch[x][1]);}
int main()
{
    n=in(),m=in();
    for(int i=1;i<=n;i++) val[i]=in();
    for(int i=1,opt,x,y;i<=m;i++){
        opt=in();x=in();
            if(opt==1){y=in();if(val[x]==-1||val[y]==-1||x==y) continue;int ffff=find(x),fff=find(y);merge(ffff,fff);}
            else {if(val[x]==-1) out(val[x]) ;else {int fmx=find(x);out(val[fmx]);pop(fmx);}}
    }
    return 0;
}

19.LCT

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int N=300005;
int n,m,a[N],fa[N],ch[N][2],sum[N];
bool rev[N];
bool is_rt(int x) {
//	if(x==0) return 1;
    return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;
}
void pushup(int x) {
    sum[x]=a[x]^sum[ch[x][0]]^sum[ch[x][1]];
}
void pushdown(int x) {
    if(rev[x]) 
        swap(ch[x][0],ch[x][1]),
        rev[ch[x][0]]^=1,
        rev[ch[x][1]]^=1,
        rev[x]=0;
}
bool ck(int x) {
    return x==ch[fa[x]][1];
}
void rotate(int x) {
    int f=fa[x],ff=fa[f];bool tag=ck(x);
    if(!is_rt(f)) ch[ff][f==ch[ff][1]]=x;
    ch[f][tag]=ch[x][tag^1];
    fa[ch[f][tag]]=f;
    ch[x][tag^1]=f;
    fa[f]=x;
    fa[x]=ff;
    pushup(f);pushup(x);
}
int top,stk[N];
void splay(int x) {
    top=0;
    stk[++top]=x;
    for(int i=x;!is_rt(i);i=fa[i]) stk[++top]=fa[i];
    for(int i=top;i;i--) pushdown(stk[i]);
    for(int f;!is_rt(x);rotate(x)) 
    if(!is_rt(f=fa[x]))rotate(ck(x)==ck(f)?f:x);
}

void access(int x) {
    for(int t=0;x;t=x,x=fa[x]) 
    splay(x),ch[x][1]=t,pushup(x);
}
void makeroot(int x) {
    access(x);
    splay(x);
    swap(ch[x][0],ch[x][1]);
    rev[ch[x][0]]^=1;rev[ch[x][1]]^=1;
}
int findroot(int x) {
    access(x);
    splay(x);
    while(ch[x][0]) x=ch[x][0];
    return x;
}
void link(int x,int y) {
    makeroot(x);
    fa[x]=y;
}
void cut(int x,int y) {
    makeroot(x);
    access(y);
    splay(y);
    if(ch[x][0]||ch[x][1]||fa[x]!=y||ch[y][ck(x)^1]) return;
    ch[y][0]=fa[x]=0;
}
void change(int x,int v) {
    a[x]=v;
    access(x);
    splay(x);
}
int query(int x,int y) {
    makeroot(x);
    access(y);
    splay(y);
    return sum[y];
}
int main() {
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    for(int i=1,opt,x,y;i<=m;i++) {
        scanf("%d%d%d",&opt,&x,&y);
        switch (opt) {
            case 0:printf("%d\n",query(x,y));break;
            case 1:if(findroot(x)!=findroot(y)) link(x,y);break;
            case 2:if(findroot(x)==findroot(y))cut(x,y);break;
            case 3:change(x,y);break;
        }
    }
}

20.FFT

include <iostream>
#include <complex>
#include <cmath>
#include <cstdio>
#include <cstring>
using namespace std;
const int N=2097153;
const double pi=acos(-1.0);
struct complexd{
    double x,y;
    complexd (double xx=0,double yy=0){x=xx,y=yy;}
    complexd operator + (const complexd &rhs) const {return complexd(x+rhs.x,y+rhs.y);}
    complexd operator - (const complexd &rhs) const {return complexd(x-rhs.x,y-rhs.y);}
    complexd operator * (const complexd &rhs) const {return complexd(x*rhs.x-y*rhs.y,x*rhs.y+y*rhs.x);}
};
inline int rd() {
    static int x;x=0;static char ch;ch=getchar();
    while(!isdigit(ch)) ch=getchar();
    while(isdigit(ch)) x=x*10+(ch^48),ch=getchar();
    return x;
}
int n,m,l,r[N];
void fft(complexd *b,short tag) {
    for(int i=0;i<n;i++) if(i<r[i]) swap(b[i],b[r[i]]);
    for(int mid=1;mid<n;mid<<=1) {
        complexd tp(cos(pi/mid),tag*sin(pi/mid));
        for(int j=0;j<n;j+=mid<<1) {
            complexd w(1,0);
            for(int k=0;k<mid;k++,w=w*tp) {
                complexd x=b[j+k],y=w*b[j+mid+k];
                b[j+k]=x+y;
                b[j+mid+k]=x-y;
            }
        }
    }
}
complexd a[N],b[N];
int main() {
    n=rd(),m=rd();
    for(int i=0,x;i<=n;i++) a[i]=rd();
    for(int j=0,x;j<=m;j++) b[j]=rd();
    m+=n;
    n=1;
    while(n<=m) n<<=1,l++;
    for(int i=0;i<n;i++) r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));
    fft(a,1);
    fft(b,1);
    for(int i=0;i<=n;i++) a[i]=a[i]*b[i];
    fft(a,-1);
    for(int i=0;i<=m;i++) printf("%d ",(int)(a[i].x/n+0.5));
    return 0;
}

21.KMP

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
char s1[1000005],s2[1000005],s[2000005];
int nxt[2000005];
int main() {
    scanf("%s%s",s1,s2);
    int len=strlen(s2);
    for(int i=1;i<=len;i++) s[i]=s2[i-1];
    s[len+1]=' ';
    int len1=strlen(s1);
    for(int i=0;i<len1;i++) s[i+len+2]=s1[i];
    nxt[0]=0;
    for(int i=2,j=0;i<=1+len+len1;i++) {
        while(j&&s[i]!=s[j+1]) j=nxt[j];
        if(s[i]==s[j+1]) j++;
        nxt[i]=j;
        if(nxt[i]==len&&i>len+1) printf("%d\n",i-len-len);
    }
//	putchar('\n');
    for(int i=1;i<=len;i++) printf("%d ",nxt[i]);
    return 0;
} 

22.LCA
https://www.cnblogs.com/sdfzhsz/p/9280879.html
23.EK求mcf

#include <queue>
#include <cctype>
#include <cstdio>
#include <cstring>
const int inf=0x3f3f3f3f,N=50005<<1;
std::queue<int> q;
int n,m,S,T,dis[N],from[N],head[N],ecnt=1,ans1,ans2;
bool inq[N];
struct Edge{int to,nxt,val,cost,from;}e[N<<1];
void add(int bg,int ed,int val,int cost){e[++ecnt].cost=cost;e[ecnt].from=bg;e[ecnt].nxt=head[bg];e[ecnt].to=ed;e[ecnt].val=val;head[bg]=ecnt;}
bool spfa(){
    q.push(S);
    std::memset(dis,0x3f,sizeof dis);
    std::memset(inq,0,sizeof inq);
    dis[S]=0;inq[S]=1;
    while(!q.empty()){
        int u=q.front();q.pop();inq[u]=0;
        for(int i=head[u],v;i;i=e[i].nxt){
            v=e[i].to;
            if(dis[v]>dis[u]+e[i].cost&&e[i].val){
                dis[v]=dis[u]+e[i].cost;
                from[v]=i;
                if(!inq[v]) q.push(v),inq[v]=1;
            }
        }
    }
    return dis[T]!=inf;
}
void min(int &x,int y){x=x<y?x:y;}
void mcf() {
    int x=inf,i=from[T];
    while(i) {min(x,e[i].val);i=from[e[i].from];}
    ans1+=x;i=from[T];
    while(i){
        e[i].val-=x;e[i^1].val+=x;
        ans2+=x*e[i].cost;i=from[e[i].from];
    }
}
inline void read(int &x){
    x=0;int f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
    x=x*f;
}
int main(){
    read(n);read(m);read(S);read(T);
    for(int i=1,a,b,c,v;i<=m;i++)read(a),read(b),read(v),read(c),add(a,b,v,c),add(b,a,0,-c);
    while(spfa())mcf();
    printf("%d %d",ans1,ans2);
}

24.AC自动机

#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
using namespace std;
int n;
const int N=500010;
struct ACZDJ {
    int tr[N][26],fail[N],val[N],cnt;
    void insert(char *s) {
        int len=strlen(s),p=0;
        for(int i=0; i<len; i++) {
            if(!tr[p][s[i]-'a']) tr[p][s[i]-'a']=++cnt;
            p=tr[p][s[i]-'a'];
        }
        val[p]++;
    }
    void build() {
        queue<int>q;
        for(int i=0; i<26; i++)
            if(tr[0][i]) q.push(tr[0][i]),fail[tr[0][i]]=0;
        while(!q.empty()) {
            int u=q.front();
            q.pop();
            for(int i=0; i<26; i++) {
                if(tr[u][i]) q.push(tr[u][i]),fail[tr[u][i]]=tr[fail[u]][i];
                else tr[u][i]=tr[fail[u]][i];
            }
        }
    }
    int query(char *s) {
        int len=strlen(s),p=0,ans=0;
        for(int i=0; i<len; i++) {
            int v=s[i]-'a';
            p=tr[p][v];
            for(int j=p; ~val[j]&&j; j=fail[j]) {
                ans+=val[j];
                val[j]=-1;
            }
        }
        return ans;
    }
} AC;
char s[2000005];
int main() {
    scanf("%d",&n);
    while(n--) {
        scanf("%s",s);
        AC.insert(s);
    }
    AC.build();
    scanf("%s",s);
    cout<<AC.query(s);
}

25.主席树

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <queue>
#include <map>
#include <set>
#include <stack>
#include <vector>
#include <cstdlib>
#include <algorithm>
#define LL long long
using namespace std;
const int N=200005<<5;
int l[N],r[N],sum[N],b[N],p[N];
int n,m,a[N],root[N],tot;
void build(int &k,int L,int R) {
    k=++tot;
    if(L<R) {
            int mid=L+R>>1;
        build(l[k],L,mid);
        build(r[k],mid+1,R);
    }
}
void update(int &k,int pre,int L,int R,int c) {
    k=++tot;
    l[k]=l[pre],r[k]=r[pre],sum[k]=sum[pre]+1;
    if(L<R) {
                int mid=L+R>>1;
        if(c<=mid)update(l[k],l[pre],L,mid,c);
        else update(r[k],r[pre],mid+1,R,c);
    }
}
int query(int u,int v,int L,int R,int k) {
    if(L==R) return L;
    int x=sum[l[v]]-sum[l[u]];
    if(x>=k) return query(l[u],l[v],L,(L+R)>>1,k);
    else return query(r[u],r[v],(L+R)/2+1,R,k-x);
}
int main() {
    cin>>n>>m;
    for(int i=1; i<=n; i++) scanf("%d",&a[i]),b[i]=a[i];
    sort(a+1,a+1+n);
    int u=unique(a+1,a+1+n)-a-1;
    build(root[0],1,u);
    for(int i=1; i<=n; i++) {
        b[i]=lower_bound(a+1,a+1+u,b[i])-a;
        update(root[i],root[i-1],1,u,b[i]);
    }
    int q,v,k;
    for(int i=1; i<=m; i++) {
        scanf("%d%d%d",&q,&v,&k);
        printf("%d\n",a[query(root[q-1],root[v],1,u,k)]);
    }
    return 0;
}

26.割点

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <vector>
#include <bitset>
#include <cmath>
#include <queue>
#include <ctime>
#include <set>
#include <map>
#define fo(i,j,k) for(int i=j;i<=k;i++)
#define fd(i,j,k) for(int i=j;i>=k;i--)
#define go(i,k) for(int i=head[k],v=e[i].to;i;i=e[i].nxt,v=e[i].to)
using namespace std;
typedef long long ll;
typedef double db;
const int inf=0x3f3f3f3f;
inline int rd() {
	int x=0,f=1;char ch=getchar();
	while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
	while(isdigit(ch)) x=x*10+(ch^48),ch=getchar();
	return x*f;
}
const int N=100005,M=1000005;
struct Edge{int to,nxt;}e[M];
int head[N],ecnt,dfn[N],low[N],tim,n,m;
bool cut[N];
inline void add(int bg,int ed) {e[++ecnt]=(Edge) {ed,head[bg]};head[bg]=ecnt;}
void tarjan(int x,int rt) {
	dfn[x]=low[x]=++tim;
	int f=0;
	go(i,x) {
		if(!dfn[v]) {
			tarjan(v,rt);
			low[x]=min(low[v],low[x]);
			if(low[v]>=dfn[x]&&x!=rt) cut[x]=1;
			if(x==rt) f++;
		}
		else low[x]=min(low[x],dfn[v]);
	}
	if(f>=2) {cut[rt]=1;}
}
int main() {
#ifdef HSZ
	freopen(".in","r",stdin);
	freopen(".out","w",stdout);
#endif
	n=rd(),m=rd();
	int a,b;
	fo(i,1,m) a=rd(),b=rd(),add(a,b),add(b,a);
	fo(i,1,n) if(!dfn[i])tarjan(i,i);
	int ans=0;
	fo(i,1,n) if(cut[i]) ans++;
	printf("%d\n",ans);
	fo(i,1,n) if(cut[i]) printf("%d ",i);
	return 0;
}
posted @ 2018-10-25 20:06  SWHsz  阅读(258)  评论(0编辑  收藏  举报