C++代码模板

Tree

并查集

ll pre[maxn];
inline ll find(ll x){return x==pre[x]?x:pre[x]=find(pre[x]);}
inline merge(ll x,ll y){pre[find(x)]=find(y);}

FHQ-Treap

struct node{int l,r,val,pri,siz;}treap[maxn];
int root,tot;
void updateroot(int p){treap[p].siz=treap[treap[p].l].siz+treap[treap[p].r].siz+1;return;}
void split(int p,int x,int&l,int&r){
    if(!p){l=r=0;return;}
    if(treap[p].val<=x)l=p,split(treap[p].r,x,treap[p].r,r);
    else r=p,split(treap[p].l,x,l,treap[p].l);
    updateroot(p);
    return;
}
inline int merge(int l,int r){
    if(!l||!r)return l+r;
    if(treap[l].pri>treap[r].pri){
        treap[l].r=merge(treap[l].r,r);
        updateroot(l);
        return l;
    }
    treap[r].l=merge(l,treap[r].l);
    updateroot(r);
    return r;
}
void newnode(int x){
    treap[++tot].siz=1;
    treap[tot].l=treap[tot].r=0;
    treap[tot].val=x,treap[tot].pri=rand();
    return;
}
inline int insert(int x){
    int l,r;split(root,x,l,r);
    newnode(x);
    root=merge(merge(l,tot),r);
    return tot;
}
inline int del(int x){
    int l,m,r;
    split(root,x,l,r);
    split(l,x-1,l,m);
    m=merge(treap[m].l,treap[m].r);
    root=merge(merge(l,m),r);
    // root=merge(l,r);//全删
    return root;
}
inline int order(int x){
    int l,r,res;
    split(root,x-1,l,r);
    res=treap[l].siz+1;
    root=merge(l,r);
    return res;
}
inline int kth(int p,int k){
    if(k==treap[treap[p].l].siz+1)return p;
    if(k<=treap[treap[p].l].siz)return kth(treap[p].l,k);
    return kth(treap[p].r,k-treap[treap[p].l].siz-1);
}
inline int front(int x){
    int l,r,res;
    split(root,x-1,l,r);
    res=treap[kth(l,treap[l].siz)].val;
    root=merge(l,r);
    return res;
}
inline int back(int x){
    int l,r,res;
    split(root,x,l,r);
    res=treap[kth(r,1)].val;
    root=merge(l,r);
    return res;
}

记得最后在int main()里面加上srand(time(NULL));

线段树

#define ls (x<<1)
#define rs (x<<1|1)
#define mid ((l+r)>>1)
ll a[maxn];
struct linetree{ll v,lazy;}t[maxn<<2];
inline void buildtree(ll x,ll l,ll r){
    if(l==r){
        t[x].v=a[id[l]]%mod;
        return;
    }
    buildtree(ls,l,mid);
    buildtree(rs,mid+1,r);
    t[x].v=(t[ls].v+t[rs].v+mod)%mod;
}
inline void pushdown(ll x,ll l,ll r){
    if(t[x].lazy){
        t[ls].lazy+=t[x].lazy,t[rs].lazy+=t[x].lazy;
        t[ls].v+=t[x].lazy*(mid-l+1),t[ls].v%=mod;
        t[rs].v+=t[x].lazy*(r-mid),t[rs].v%=mod;
        t[x].lazy=0;
    }
}
inline void treeupdate(ll x,ll l,ll r,ll s,ll e,ll val){
    if(s<=l&&r<=e){
        t[x].lazy+=val,t[x].lazy%=mod;
        t[x].v+=val*(r-l+1),t[x].v%=mod;
        return;
    }
    pushdown(x,l,r);
    if(mid>=s)treeupdate(ls,l,mid,s,e,val);
    if(mid<e)treeupdate(rs,mid+1,r,s,e,val);
    t[x].v=(t[ls].v+t[rs].v+mod)%mod;
}
inline ll treeask(ll x,ll l,ll r,ll s,ll e){
    if(s<=l&&r<=e)return t[x].v;
    pushdown(x,l,r);
    ll ans=0;
    if(mid>=s)ans+=treeask(ls,l,mid,s,e);
    if(mid<e)ans+=treeask(rs,mid+1,r,s,e);
    return ans%mod;
}

重链剖分

#define ls (x<<1)
#define rs (x<<1|1)
#define mid ((l+r)>>1)
ll n,m,root,mod,top[maxn],dep[maxn],fa[maxn],siz[maxn],son[maxn],head[maxn],tot,dfn[maxn],id[maxn],cnt,a[maxn];
struct edge{ll to,nxt;}e[maxn<<1];
inline void add(ll u,ll v){e[++tot]=(edge){v,head[u]},head[u]=tot;}
struct linetree{ll v,lazy;}t[maxn<<2];
inline void buildtree(ll x,ll l,ll r){
    if(l==r){
        t[x].v=a[id[l]]%mod;
        return;
    }
    buildtree(ls,l,mid);
    buildtree(rs,mid+1,r);
    t[x].v=(t[ls].v+t[rs].v+mod)%mod;
}
inline void pushdown(ll x,ll l,ll r){
    if(t[x].lazy){
        t[ls].lazy+=t[x].lazy,t[rs].lazy+=t[x].lazy;
        t[ls].v+=t[x].lazy*(mid-l+1),t[ls].v%=mod;
        t[rs].v+=t[x].lazy*(r-mid),t[rs].v%=mod;
        t[x].lazy=0;
    }
}
inline void treeupdate(ll x,ll l,ll r,ll s,ll e,ll val){
    if(s<=l&&r<=e){
        t[x].lazy+=val,t[x].lazy%=mod;
        t[x].v+=val*(r-l+1),t[x].v%=mod;
        return;
    }
    pushdown(x,l,r);
    if(mid>=s)treeupdate(ls,l,mid,s,e,val);
    if(mid<e)treeupdate(rs,mid+1,r,s,e,val);
    t[x].v=(t[ls].v+t[rs].v+mod)%mod;
}
inline ll treeask(ll x,ll l,ll r,ll s,ll e){
    if(s<=l&&r<=e)return t[x].v;
    pushdown(x,l,r);
    ll ans=0;
    if(mid>=s)ans+=treeask(ls,l,mid,s,e);
    if(mid<e)ans+=treeask(rs,mid+1,r,s,e);
    return ans%mod;
}
inline void dfs1(ll u,ll pre){
    fa[u]=pre,siz[u]=1,dep[u]=dep[pre]+1;
    for(ll i=head[u];i;i=e[i].nxt){
        ll v=e[i].to;
        if(v==pre)continue;
        dfs1(v,u);
        siz[u]+=siz[v];
        if(siz[son[u]]<siz[v])son[u]=v;
    }
}
inline void dfs2(ll u,ll tf){
    top[u]=tf,dfn[u]=++cnt,id[cnt]=u;
    if(son[u])dfs2(son[u],tf);
    for(ll i=head[u];i;i=e[i].nxt){
        ll v=e[i].to;
        if(v==fa[u]||v==son[u])continue;
        dfs2(v,v);
    }
}
inline ll lca(ll u,ll v){
    while(top[u]!=top[v]){
        if(dep[fa[top[u]]]<dep[fa[top[v]]])swap(u,v);
        u=fa[top[u]];
    }
    if(dep[u]>dep[v])swap(u,v);
    return u;
}
inline ll query(ll u,ll v){
    ll ans=0;
    while(top[u]!=top[v]){
        if(dep[fa[top[u]]]<dep[fa[top[v]]])swap(u,v);
        ans+=treeask(1,1,n,dfn[top[u]],dfn[u]),ans%=mod;
        u=fa[top[u]];
    }
    if(dep[u]>dep[v])swap(u,v);
    ans+=treeask(1,1,n,dfn[u],dfn[v]),ans%=mod;
    return ans;
}
inline void modify(ll u,ll v,ll w){
    while(top[u]!=top[v]){
        if(dep[fa[top[u]]]<dep[fa[top[v]]])swap(u,v);
        treeupdate(1,1,n,dfn[top[u]],dfn[u],w);
        u=fa[top[u]];
    }
    if(dep[u]>dep[v])swap(u,v);
    treeupdate(1,1,n,dfn[u],dfn[v],w);
}

Graph

最短路

Dijkstra

ll n,m,u,v,val,cnt,head[maxn],dis[maxn],f;
struct edge{ll to,nxt,val;}e[maxn];
inline void add(ll u,ll v,ll val){e[++cnt]=edge{v,head[u],val},head[u]=cnt;}
struct node{
    ll num,val;
    inline bool operator<(const node&u)const{return val>u.val;}
};
inline void dijkstra(){
    for(ll i=1;i<=n;++i)dis[i]=1e9;
    std::priority_queue<node>p;
    p.push(node{f,0}),dis[f]=0;
    while(!p.empty()){
        node u=p.top();
        p.pop();
        if(dis[u.num]!=u.val)continue;
        for(ll i=head[u.num];i;i=e[i].nxt){if(dis[u.num]+e[i].val<dis[e[i].to]){dis[e[i].to]=dis[u.num]+e[i].val,p.push(node{e[i].to,dis[e[i].to]});}
        }
    }
}

SPFA

struct edge{ll to,nxt,val;}e[maxm];
ll dis[maxn],head[maxn];
bool vis[maxn];
inline void spfa(ll x){
    memset(dis,0x3f3f3f3f,sizeof(dis));
    queue<ll>q;
    q.push(x),vis[x]=1,dis[x]=0;
    while(!q.empty()){
        ll u=q.front();q.pop();vis[u]=0;
        for(ll i=head[u];i;i=e[i].nxt){
            ll v=e[i].to;
            if(dis[u]+e[i].val<dis[v]){
                dis[v]=dis[u]+e[i].val;
                if(!vis[v]){
                    vis[v]=1;
                    q.push(v);
                }
            }
        }
    }
}

Floyd

ll n,m,dis[105][105];
inline void floyd(){
	memset(dis,0x3f3f3f3f,sizeof(dis));
    for(ll i=1;i<=n;++i)dis[i][i]=0;
    while(m--){
        ll u=read(),v=read(),w=read();
        dis[u][v]=min(dis[u][v],w);
        dis[v][u]=min(dis[v][u],w);
    }
    for(ll k=1;k<=n;++k){
        for(ll i=1;i<=n;++i){
            for(ll j=1;j<=n;++j){
                dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
            }
        }
    }
}

二分图最大匹配

ll head[maxn],tot,match[maxn],ans;
struct edge{ll to,nxt;}e[maxm];
inline void add(ll u,ll v){e[++tot]=(edge){v,head[u]},head[u]=tot;}
bool vis[maxn];
inline bool dfs(ll u){
    for(ll i=head[u];i;i=e[i].nxt){
        ll v=e[i].to;
        if(!vis[v]){
            vis[v]=1;
            if(!match[v]||dfs(match[v])){
                match[v]=u;
                return 1;
            }
        }
    }
    return 0;
}

Mathmatics

快速幂

inline ll qpow(ll a,ll b){
	ll res=1;
	while(b){
		if(b&1)res=res*a%mod;
		a=a*a%mod,b>>=1;
	}
	return res;
}

素数筛

ll big[maxn],num[maxn],tot;
bool vis[maxn];
inline void prime_set(ll n){
	vis[0]=vis[1]=1;
	for(ll i=2;i<=n;++i){
		if(!vis[i]){
            big[i]=i,num[++tot]=i;
        }
        for(ll j=1;j<=tot&&i*num[j]<=n;++j){
            vis[i*num[j]]=1;
            big[i*num[j]]=big[i];
            if(i%num[j]==0)break;
        }
	}
}

欧拉函数

inline ll euler(ll k){
    ll res=k;
    for(ll i=2;i*i<=k;++i){
        if(k%i==0){
            res=res*1.0/i*(i-1);
            while(k%i==0)k/=i;
        }
    }
    if(k>1)res=res/k*(k-1);
    return res;
}

求因子/因子和

ll prime[maxn],num[maxn];
ll lcm(ll k){
    ll cnt=0,ans=1;
    for(ll i=2;i*i<=k;++i){
        if(k%i==0){
            prime[++cnt]=i;
            while(k%i==0)n/=i,++num[cnt];
        }
    }
    if(k>1)prime[++cnt]=n,++num[cnt];
    for(ll i=1;i<=cnt;++i)printf("%lld^%lld\n",prime[i],num[i]);
    for(ll i=1;i<=cnt;++i)ans*=(num[i]+1);
}

矩乘

struct matrix{
    ll a[maxn][maxn];
    inline matrix operator*(matrix t){
        matrix res;
        for(ll i=0;i<x;++i)for(ll j=0;j<x;++j)res.a[i][j]=0;
        for(ll i=0;i<x;++i)
            for(ll j=0;j<x;++j)
                for(ll k=0;k<x;++k)
                    res.a[i][j]=(res.a[i][j]+a[i][k]*t.a[k][j]%mod)%mod;
        return res;
    }
    inline matrix operator^(ll b){
        matrix res,a=*this;
        for(ll i=0;i<x;++i)for(ll j=0;j<x;++j)res.a[i][j]=(i==j);
        while(b){
            if(b&1)res=res*a;
            a=a*a,b>>=1;
        }
        return res;
    }
};

Lucas求组合数

inline ll qpow(ll a,ll b){
    ll res=1;
    while(b){
        if(b&1)res=res*a%mod;
        a=a*a%mod,b>>=1;
    }
    return res;
}
inline ll C(ll n,ll m){
    if(m<0||n<m)return 0;
    if(m>n-m)m=n-m;
    ll up=1,down=1;
    for(ll i=0;i<m;++i)up=up*(n-i)%mod,down=down*(i+1)%mod;
    return up*qpow(down,mod-2)%mod;
}
inline ll lucas(ll a,ll b){
    if(a<mod&&b<mod)return C(a,b);
    return C(a%mod,b%mod)*lucas(a/mod,b/mod)%mod;
}

乘法逆元

ll inv=qpow(a,p-2);//a在模p意义下的逆元

线性基

const ll maxn=1e5+5,maxj=25;
struct basis{
    ll p[maxj];
    inline ll highbit(ll x){ll res=0;while(x)++res,x>>=1;return res;}
    inline void ins(basis lst,ll x){*this=lst;while(x){ll dis=highbit(x);if(p[dis])x^=p[dis];else return p[dis]=x,void();}}
    inline ll size(){ll res=0;for(ll i=1;i<=maxj;++i)res+=p[i]!=0;return res;}
    inline ll sum(ll x){ll res=0;while(x){ll dis=highbit(x);if(p[dis])x^=p[dis],++res;else return -1;}return x?res:size();}
}base[maxn];
posted @ 2024-01-26 21:33  run-away  阅读(107)  评论(0)    收藏  举报