模板库

基本框架

#include <bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof(a))
#define fre(z) freopen(z".in","r",stdin),freopen(z".out","w",stdout)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef __int128 lll;
typedef pair<int,int> Pair;
const double eps=1e-8;
const int inf=2139062143;
#ifdef ONLINE_JUDGE
static char buf[1000000],*p1=buf,*p2=buf,obuf[1000000],*p3=obuf;
#define getchar() p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++
#endif
inline void qread(){}template<class T1,class ...T2>
inline void qread(T1 &a,T2&... b){
    register T1 x=0;register bool f=false;char ch=getchar();
    while(ch<'0') f|=(ch=='-'),ch=getchar();
    while(ch>='0') x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
    x=(f?-x:x);a=x;qread(b...);
}
template<class T> T qmax(T x,T y){return x>y?x:y;}
template<class T,class ...Arg> T qmax(T x,T y,Arg ...arg){return qmax(x>y?x:y,arg...);}
template<class T> T qmin(T x,T y){return x<y?x:y;}
template<class T,class ...Arg> T qmin(T x,T y,Arg ...arg){return qmin(x<y?x:y,arg...);}
template<class T> T randint(T l,T r){static mt19937 eng(time(0));uniform_int_distribution<T>dis(l,r);return dis(eng);}
int main(){
    #ifndef ONLINE_JUDGE
    system("pause");
    #endif
    return 0;
}

数据结构

并查集

void makeSet(int sz){for(int i=1;i<=sz;i++) fa[i]=i;}
int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
void unionSet(int x,int y){fa[find(x)]=find(y);}

线段树

struct Seg_tree{
    #define ls p<<1
    #define rs p<<1|1
    #define mid ((l+r)>>1)
    int tr[MAXN<<2],tag[MAXN<<2];
    inline void pup(int p){tr[p]=tr[ls]+tr[rs];}
    inline void f(int p,int l,int r,int k){tr[p]+=(r-l+1)*k;tag[p]+=k;}
    void pwn(int p,int l,int r){
        f(ls,l,mid,tag[p]);f(rs,mid+1,r,tag[p]);tag[p]=0;
    }
    void build(int a[],int p,int l,int r){
        tag[p]=0;if(l==r) tr[p]=a[l];
        else build(a,ls,l,mid),build(a,rs,mid+1,r),pup(p);
    }
    void upd(int p,int l,int r,int L,int R,int k){
        if(L<=l&&r<=R) f(p,l,r,k);
        else{
            pwn(p,l,r);if(L<=mid) upd(ls,l,mid,L,R,k);
            if(R>mid) upd(rs,mid+1,r,L,R,k);pup(p);
        }
    }
    int que(int p,int l,int r,int L,int R){
        if(L<=l&&r<=R) return tr[p];
        else{
            int res=0;pwn(p,l,r);
            if(L<=mid) res+=que(ls,l,mid,L,R);
            if(R>mid) res+=que(rs,mid+1,r,L,R);return res;
        }
    }
    #undef mid
}st;

树链剖分

int hson[MAXN],fa[MAXN],cnt[MAXN],dep[MAXN],val[MAXN],top[MAXN],id[MAXN],a[MAXN];
void dfs(int u,int f){
    cnt[u]=1;
    for(auto son:Tree[u]){
        if(son==f) continue;
        dep[son]=dep[u]+1;fa[son]=u;
        dfs(son,u);cnt[u]+=cnt[son];
        if(cnt[son]>cnt[hson[u]]) hson[u]=son;
    }
}
void dfs1(int u,int f,int t){
    id[u]=++tot;a[tot]=val[u];top[u]=t;
    if(hson[u]) dfs1(hson[u],u,t);
    for(auto son:Tree[u]) if(son!=hson[u]&&son!=f) dfs1(son,u,son);
}
void update_chain(int x,int y,int k){
    int fx=top[x],fy=top[y];
    while(fx!=fy){
        if(dep[fx]<dep[fy]) swap(fx,fy),swap(x,y);
        update(1,1,tot,id[fx],id[x],k);
        x=fa[fx],fx=top[x];
    }
    if(id[x]>id[y]) swap(x,y);
    update(1,1,tot,id[x],id[y],k);
}
int query_chain(int x,int y){
    int res=0,fx=top[x],fy=top[y];
    while(fx!=fy){
        if(dep[fx]<dep[fy]) swap(fx,fy),swap(x,y);
        res+=query(1,1,tot,id[fx],id[x]);
        x=fa[fx],fx=top[x];
    }
    if(id[x]>id[y]) swap(x,y);
    res+=query(1,1,tot,id[x],id[y]);
    return res%mod;
}
int lca(int x,int y){
    int fx=top[x],fy=top[y];
    while(fx!=fy){
        if(dep[fx]<dep[fy]) swap(fx,fy),swap(x,y);
        x=fa[fx],fx=top[x];
    }
    if(dep[x]>dep[y]) swap(x,y);
    return x;
}

李超线段树

#define mid ((l+r)>>1)
#define ls p<<1
#define rs p<<1|1
struct Line{
    int k,b;Line(){;}
    Line(int _k,int _b):k(_k),b(_b){}
    int operator () (const int x){return x*k+b;}
}tr[MAXN<<4];
void build(int p,int l,int r){
    tr[p]=Line(0,inf);
    if(l==r) return;
    build(ls,l,mid);build(rs,mid+1,r);
}
void upd(int p,int l,int r,Line f){
    if(f(l)>=tr[p](l)&&f(r)>=tr[p](r)) return;
    else if(f(l)<=tr[p](l)&&f(r)<=tr[p](r)) tr[p]=f;
    else upd(ls,l,mid,f),upd(rs,mid+1,r,f);
}
int que(int p,int l,int r,int x){
    if(l==r) return tr[p](x);
    if(mid>=x) return qmin(tr[p](x),que(ls,l,mid,x));
    else return qmin(tr[p](x),que(rs,mid+1,r,x));
}
#undef mid

图论

链式前向星

int head[MAXN];
struct Edge{
    int to,dis,nxt;
    Edge(){;}Edge(int _to,int _dis,int _nxt):to(_to),dis(_dis),nxt(_nxt){}
};vector<Edge>edge;
void add_edge(int u,int v,int w){edge.push_back(Edge{v,w,head[u]});head[u]=edge.size()-1;}

dijkstra

priority_queue<Pair>q;
int dis[MAXN];bitset<MAXN>vis;
void dijkstra(int s){
    mem(dis,0x7f);dis[s]=0;
    q.push(Pair(0,s));
    while(!q.empty()){
        int u=q.top().second;q.pop();
        if(vis[u]) continue;vis[u]=true;
        for(int i=head[u];i!=-1;i=edge[i].nxt){
            int v=edge[i].to;
            if(dis[v]>dis[u]+edge[i].dis){
                dis[v]=dis[u]+edge[i].dis;
                q.push(Pair(-dis[v],v));
            }
        }
    }
}

SPFA

int dis[MAXN],cnt[MAXN];
bitset<MAXN>inq;queue<int>q;
bool spfa(int s){
    mem(dis,0x3f);mem(cnt,0);inq.reset();
    q.push(s);dis[s]=0;inq[s]=true;cnt[s]=1;
    while(!q.empty()){
        int u=q.front();q.pop();cnt[u]=0;inq[u]=false;
        for(int i=head[u];i!=-1;i=edge[i].nxt){
            int v=edge[i].to;
            if(dis[v]>dis[u]+edge[i].dis){
                dis[v]=dis[u]+edge[i].dis;
                if(cnt[v]>=n) return false;
                if(!inq[v]){
                    q.push(v);
                    cnt[v]++;
                    inq[v]=true;
                }
            }
        }
    }
    return true;
}

Kruskal

void kruskal(){
    for(int i=0;i<edge.size();i++){
        int x=edge[i].u,y=edge[i].v;
        if(unionSet(x,y)) continue;
        ans+=edge[i].w;
        if(++cnt==n-1) break;
    }
}

prim

priority_queue<Edge>q;
int d[MAXN];
bool vis[MAXN];
void prim(int v0){
    mem(d,0x7f);
    d[v0]=0;
    q.push(Edge{v0,0});
    for(int i=1;i<=n;i++){
        int u=q.top().to;q.pop();
        while(vis[u]){
            u=q.top().to;
            q.pop();
        }
        vis[u]=true;
        ans+=d[u];
        for(int j=0;j<edge[u].size();j++){
            int v=edge[u][j].to;
            if(!vis[v]&&edge[u][j].dis<d[v]){
                d[v]=edge[u][j].dis;
                q.push(Edge{v,d[v]});
            }
        }
    }
}

拓扑排序

vector<int>topo;
void topo_sort(){
    topo.clear();
    queue<int>q;
    int i,j;
    for(i=1;i<=n;i++) if(!in[i]) q.push(i);
    while(!q.empty()){
        int u=q.front();q.pop();
        topo.push_back(u);
        for(i=0;i<edge[u].size();i++) if(!(--in[edge[u][i]])) q.push(edge[u][i]);
    }
}

匈牙利算法

bool match(int u){
    for(int i=head[u];i!=-1;i=edge[i].nxt){
        int v=edge[i].to;
        if(!vis[v]){
            vis[v]=true;
            if(!p[v]||match(p[v])) return p[v]=u,true;
        }
    }
    return false;
}

KM

int ex_boy[MAXN],ex_girl[MAXN],p[MAXN],slack[MAXN];
bitset<MAXN>vis_boy,vis_girl;
int a[MAXN][MAXN];
bool match(int u){
    vis_boy[u]=true;
    for(int v=1;v<=n;v++){
        if(vis_girl[v]) continue;
        int d=ex_boy[u]+ex_girl[v]-a[u][v];
        if(!d){
            vis_girl[v]=true;
            if(!p[v]||match(p[v])) return p[v]=u,true;
        }
        else slack[v]=qmin(slack[v],d);
    }
    return false;
}
int KM(){
    int i,j;vis_boy.reset();
    for(i=1;i<=n;i++){
        ex_boy[i]=a[i][1];
        for(j=2;j<=n;j++) ex_boy[i]=qmax(ex_boy[i],a[i][j]);
    }
    for(i=1;i<=n;i++){
        fill(slack+1,slack+n+1,2139062143);
        while(1){
            vis_boy.reset();vis_girl.reset();
            if(match(i)) break;
            int d=2139062143;
            for(j=1;j<=n;j++) if(!vis_girl[j]) d=qmin(d,slack[j]);
            for(j=1;j<=n;j++){
                if(vis_boy[j]) ex_boy[j]-=d;
                if(vis_girl[j]) ex_girl[j]+=d;
                else slack[j]-=d;
            }
        }
    }
    int res=0;
    for(i=1;i<=n;i++) res+=a[p[i]][i];
    return res;
}

Tarjan

bitset<MAXN>instack;
int dfn[MAXN],low[MAXN],s[MAXN],top,cnt;
int scc[MAXN],sc,sz[MAXN],f[MAXN];
void tarjan(int u){
    low[u]=dfn[u]=++cnt;s[++top]=u;instack[u]=true;
    for(int i=head[u];i!=-1;i=edge[i].nxt){
        const int &v=edge[i].to;
        if(!dfn[v]){
            tarjan(v);
            low[u]=qmin(low[u],low[v]);
        }
        else if(instack[v]) low[u]=qmin(low[u],dfn[v]);
    }
    if(low[u]==dfn[u]){
        sc++;
        while(s[top+1]!=u){
            scc[s[top]]=sc;
            sz[sc]++;
            instack[s[top--]]=false;
        }
    }
}

数论

埃氏筛

bool isprime[MAXN];
void sieve(int size){
    for(int i=2;i<=size;i++) isprime[i]=true;
    for(int i=2;i<=size;i++)
        if(isprime[i]) for(int j=i+i;j<=size;j+=i) isprime[j]=false;
}

普通判断素数

bool prime(int x) {
	if(x==2) return true;
    if(x==1||!(x&1))return 0;
    else{
        for(int i=2;i<=sqrt(x);i++) if(x%i==0) return false;
        return true;
    }
}

Miller-Rabin

int fastpow(int base,int power,int modx){
    int res=1;
    while(power){
        if(power&1) res=(__int128)res*base%modx;
        power>>=1;
        base=(__int128)base*base%modx;
    }return res%modx;
}
int ud[]={2,3,5,7,11,13,17,19,23};
bool check(int n,int m,int k,int a){
    if(n==a) return true;
    int v=fastpow(a,m,n);
    if(v==1) return true;
    for(int i=0;i<k;i++){
        int x=(__int128)v*v%n;
        if(x==1) return v==n-1;
        v=x;
    }return false;
}
bool Miller_Rabin(int x){
    if(x==2) return true;
    if(x<2||!(x&1)) return false;
    int m=x-1,k=0;while(!(m&1)) k++,m>>=1;
    for(auto a:ud) if(!check(x,m,k,a)) return false;
    return true;
}

Pollard-Rho

int ud[]={2,3,5,7,11,13,17,19,23};
bool check(int n,int m,int k,int a){
    if(n==a) return true;
    int v=fastpow(a,m,n);
    if(v==1) return true;
    for(int i=0;i<k;i++){
        int x=(__int128)v*v%n;
        if(x==1) return v==n-1;
        v=x;
    }return false;
}
bool Miller_Rabin(int x){
    if(x==2) return true;
    if(x<2||!(x&1)) return false;
    int m=x-1,k=0;while(!(m&1)) k++,m>>=1;
    for(auto a:ud) if(!check(x,m,k,a)) return false;
    return true;
}
int gcd(int x,int y){return y?gcd(y,x%y):x;}
int Pollard_Rho(int n){
    int r=0,t=0,c=randint(1ll,n-1);
    int stp=0,goal=1,q=1;
    auto f=[=](int x){return ((lll)x*x+c)%n;};
    for(goal=1;;goal<<=1,r=t,q=1){
        for(stp=1;stp<=goal;stp++){
            t=f(t);q=(lll)q*abs(t-r)%n;
            if(!(stp%127)){
                int d=gcd(q,n);
                if(d>1) return d;
            }
        }
        int d=gcd(q,n);
        if(d>1) return d;
    }
}

扩展欧几里得

int exgcd(int a,int b,int &x,int &y){
    if(!b) return x=1,y=0,a;
    int d=exgcd(b,a%b,x,y);
    int z=x;x=y;y=z-y*(a/b);
    return d;
}
posted @ 2022-05-09 11:57  l_x_y  阅读(64)  评论(0编辑  收藏  举报