C++ 常用模板

常用模板:

卡常

快读快写
int read(){
    int k=0,f=1;
    char c=getchar_unlocked();
    while(c<'0'||c>'9'){
        if(c=='-') f=-1;
        c=getchar_unlocked();
    }
    while(c>='0'&&c<='9') k=k*10+c-'0',c=getchar_unlocked();
    return k*f;
}
void write(int x){
    if(x<0) putchar('-'),x=-x;
    if(x<10) putchar(x+'0');
    else write(x/10),putchar(x%10+'0');
}
火车头
#pragma GCC optimize(3)
#pragma GCC target("avx")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#pragma GCC optimize("-fgcse")
#pragma GCC optimize("-fgcse-lm")
#pragma GCC optimize("-fipa-sra")
#pragma GCC optimize("-ftree-pre")
#pragma GCC optimize("-ftree-vrp")
#pragma GCC optimize("-fpeephole2")
#pragma GCC optimize("-ffast-math")
#pragma GCC optimize("-fsched-spec")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("-falign-jumps")
#pragma GCC optimize("-falign-loops")
#pragma GCC optimize("-falign-labels")
#pragma GCC optimize("-fdevirtualize")
#pragma GCC optimize("-fcaller-saves")
#pragma GCC optimize("-fcrossjumping")
#pragma GCC optimize("-fthread-jumps")
#pragma GCC optimize("-funroll-loops")
#pragma GCC optimize("-fwhole-program")
#pragma GCC optimize("-freorder-blocks")
#pragma GCC optimize("-fschedule-insns")
#pragma GCC optimize("inline-functions")
#pragma GCC optimize("-ftree-tail-merge")
#pragma GCC optimize("-fschedule-insns2")
#pragma GCC optimize("-fstrict-aliasing")
#pragma GCC optimize("-fstrict-overflow")
#pragma GCC optimize("-falign-functions")
#pragma GCC optimize("-fcse-skip-blocks")
#pragma GCC optimize("-fcse-follow-jumps")
#pragma GCC optimize("-fsched-interblock")
#pragma GCC optimize("-fpartial-inlining")
#pragma GCC optimize("no-stack-protector")
#pragma GCC optimize("-freorder-functions")
#pragma GCC optimize("-findirect-inlining")
#pragma GCC optimize("-fhoist-adjacent-loads")
#pragma GCC optimize("-frerun-cse-after-loop")
#pragma GCC optimize("inline-small-functions")
#pragma GCC optimize("-finline-small-functions")
#pragma GCC optimize("-ftree-switch-conversion")
#pragma GCC optimize("-foptimize-sibling-calls")
#pragma GCC optimize("-fexpensive-optimizations")
#pragma GCC optimize("-funsafe-loop-optimizations")
#pragma GCC optimize("inline-functions-called-once")
#pragma GCC optimize("-fdelete-null-pointer-checks")
#pragma GCC optimize(2)

数学

组合数
void init(){jc[0]=1;for(int i=1;i<N;i++) jc[i]=jc[i-1]*i%mod;} 
ll ksm(ll a,ll b){
	ll ct=1;
	while(b){
		if(b&1) ct=ct*a%mod;
		b>>=1,a=a*a%mod;
	}
	return ct;
}
ll C(ll n,ll m){return jc[n]*ksm(jc[n-m],mod-2)%mod*ksm(jc[m],mod-2)%mod;}
组合数(卡常)
ll ksm(ll a,ll b){
	ll ct=1;
	while(b){
		if(b&1) ct=ct*a%mod;
		a=a*a%mod;b>>=1;
	}
	return ct;
}
ll C(ll m,ll n){return jc[n]*inv[m]%mod*inv[n-m]%mod;}
void init(){
    jc[0]=1;
	for(int i=1;i<=n;i++) jc[i]=jc[i-1]*i%mod;
	inv[n]=ksm(jc[n],mod-2);
	for(int i=N-11;~i;i--) inv[i]=inv[i+1]*(i+1)%mod;
}
矩阵
struct Mat{
	ll a[N][N]={};
	Fbn operator*(const Mat &b){
		Fbn s;
		for(ll k=1;k<=n;k++)
			for(ll i=1;i<=n;i++)
				for(ll j=1;j<=n;j++)
					s.a[i][j]=(s.a[i][j]+a[i][k]*b.a[k][j]%mod)%mod;
		return s;
	}
}ans,base;
ll ksm(ll p){
	while(p){
		if(p&1) ans=ans*base;
		base=base*base;
		p>>=1;
	}
	return 0;
}
逆元
for(ll i=2;i<=n;i++) dp[i]=(p-p/i)*dp[p%i]%p;

数据结构

线段树
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll N=1e5+10;
ll b,p,q,k,n,m,t[N*4],a[N],lazy[N*4];
void build(ll rt,ll l,ll r){
	if(l==r){t[rt]=a[l];return;}
	ll mid=l+r>>1;
	build(rt<<1,l,mid);build((rt<<1)+1,mid+1,r);
	t[rt]=t[rt<<1]+t[(rt<<1)+1];
}
void fun(ll rt,ll l,ll r,ll v){t[rt]+=(r-l+1)*v;lazy[rt]+=v;}
void pushdown(ll rt,ll l,ll r){
	ll mid=l+r>>1;
	fun(rt<<1,l,mid,lazy[rt]);fun((rt<<1)+1,mid+1,r,lazy[rt]);
	lazy[rt]=0;
}
void update(ll rt,ll l,ll r,ll rl,ll rr,ll k){
	if(r<rl||rr<l) return;
	if(l>=rl&&rr>=r){fun(rt,l,r,k);return;}
	pushdown(rt,l,r);
	ll mid=l+r>>1;
	update(rt<<1,l,mid,rl,rr,k);update((rt<<1)+1,mid+1,r,rl,rr,k);
	t[rt]=t[rt<<1]+t[(rt<<1)+1];
}
ll query(ll rt,ll l,ll r,ll rl,ll rr){
	if(r<rl||rr<l) return 0;
	if(l>=rl&&rr>=r) return t[rt];
	pushdown(rt,l,r);
	ll mid=l+r>>1;
	return query(rt<<1,l,mid,rl,rr)+query((rt<<1)+1,mid+1,r,rl,rr);
}
树状数组1
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define lowbit(x) (x)&(-(x))
const ll N=5e5+10;
ll n,m,l,x,y,s[N],a;
void xg(ll x,ll k){while(x<=n) s[x]+=k,x+=lowbit(x);}
ll sum(ll x){
	ll ct=0;
	while(x) ct+=s[x],x-=lowbit(x);
	return ct;
}
ll getsum(ll l,ll r){return sum(r)-sum(l-1);}
树状数组
void xg(ll s[],ll x,ll k){while(x<=n) s[x]+=k,x+=lowbit(x);}
void qxg(ll x,ll y,ll k){
	xg(s,x,k);xg(s,y+1,-k);
	xg(s2,x,x*k);xg(s2,y+1,-(y+1)*k);
}
ll sum(ll s[],ll x){
	ll ct=0;
	while(x) ct+=s[x],x-=lowbit(x);
	return ct;
}
ll getsum(ll l,ll r){return (r+1)*sum(s,r)-sum(s2,r)-l*sum(s,l-1)+sum(s2,l-1);}
平衡树
ll New(ll x){val[++ct]=x,da[ct]=rand(),sz[ct]=cnt[ct]=1;return ct;}
void up(ll rt){sz[rt]=sz[son[rt][0]]+sz[son[rt][1]]+cnt[rt];}
void build(){root=New(-inf),son[root][1]=New(inf),up(root);}
void ro(ll &rt,bool d){// rotate
	ll t=son[rt][!d];son[rt][!d]=son[t][d],son[t][d]=rt,rt=t;
	up(son[rt][d]),up(rt);
}
void in(ll &rt,ll x){// insert
	if(!rt){rt=New(x);return;}
	if(val[rt]==x){cnt[rt]++,up(rt);return;}
	bool d=(x>val[rt]);in(son[rt][d],x);
	if(da[rt]<da[son[rt][d]]) ro(rt,!d);
	up(rt);
}
void de(ll &rt,ll x){// delete
	if(!rt) return;
	if(val[rt]==x){
		if(cnt[rt]>1){cnt[rt]--;up(rt);return;}
		if(son[rt][0]||son[rt][1]){
			if(!son[rt][1]||da[son[rt][0]]>da[son[rt][1]]) ro(rt,1),de(son[rt][1],x);
			else ro(rt,0),de(son[rt][0],x);
			up(rt);
		}else rt=0;
		return;
	}
	if(x<val[rt]) de(son[rt][0],x);
	else de(son[rt][1],x);
	up(rt);
}
ll ra(ll rt,ll x){// rank
	if(!rt) return 1;
	if(val[rt]==x) return sz[son[rt][0]]+1;
	if(val[rt]>x) return ra(son[rt][0],x);
	return sz[son[rt][0]]+cnt[rt]+ra(son[rt][1],x);
}
ll se(ll rt,ll x){// search
	if(!rt) return inf;
	if(x<=sz[son[rt][0]]) return se(son[rt][0],x);
	if(x<=sz[son[rt][0]]+cnt[rt]) return val[rt];
	return se(son[rt][1],x-sz[son[rt][0]]-cnt[rt]);
}
ll pr(ll x){// pre
	ll rt=root,p=0;
	while(rt)
		if(val[rt]<x) p=val[rt],rt=son[rt][1];
		else rt=son[rt][0];
	return p;
}
ll ne(ll x){// next
	ll rt=root,p=0;
	while(rt)
		if(val[rt]>x) p=val[rt],rt=son[rt][0];
		else rt=son[rt][1];
	return p;
}

图论/树论

dijkstra
void dijkstra(ll s){
	set<pair<ll,ll> > q;
	for(int i=1;i<=n;i++) dist[i]=inf;
	dist[s]=0;
	for(int i=1;i<=n;i++) q.insert({dist[i],i});
	while(!q.empty()){
		ll x=q.begin()->second;
		q.erase(q.begin());
		if(dist[x]==inf) break;
		for(auto y:e[x]){
			if(dist[x]+y.second<dist[y.first]){
				q.erase({dist[y.first],y.first});
				dist[y.first]=dist[x]+y.second;
				q.insert({dist[y.first],y.first});
			}
		}
	}
}
lca
void dfs(ll x,ll fa){
	f[x][0]=fa,d[x]=d[fa]+1;
	for(int i=1;i<=20;i++)
		f[x][i]=f[f[x][i-1]][i-1];
	for(auto y:e[x])
		if(y!=fa) dfs(y,x);
}
ll lca(ll x,ll y){
	if(d[x]>d[y]) x^=y^=x^=y;
	for(int i=20;i>=0;i--)
		if(d[f[y][i]]>=d[x]) y=f[y][i];
	if(x==y) return x;
	for(int i=20;i>=0;i--)
		if(f[x][i]^f[y][i]) x=f[x][i],y=f[y][i];
	return f[x][0];
}
lca(树剖版)
void dfs(ll x){
    sz[x]=1,d[x]=d[f[x]]+1;
    for(auto y:e[x]) if(y!=f[x]) f[y]=x,dfs(y),sz[x]+=sz[y];
}
void dfs1(ll x){
    ll t=0;
    if(!top[x]) top[x]=x;
    for(auto y:e[x]) if(y!=f[x]&&sz[y]>sz[t]) t=y;
    if(t) top[t]=top[x],dfs1(t);
    for(auto y:e[x]) if(y!=f[x]&&t!=y) dfs1(y);
}
ll lca(ll x,ll y){
    while(top[x]!=top[y]){
        if(d[top[x]]<d[top[y]]) x^=y^=x^=y;
        x=f[top[x]];
    }
    if(d[x]>d[y]) x^=y^=x^=y;
    return x;
}
树剖
void xg(ll s[],ll x,ll k){while(x<=n) s[x]+=k,s[x]%=p,x+=lowbit(x);}
void qxg(ll x,ll y,ll k){
	xg(s,x,k);xg(s,y+1,-k);
	xg(s2,x,x*k);xg(s2,y+1,-(y+1)*k);
}
ll sum(ll s[],ll x){
	ll ct=0;
	while(x) ct+=s[x],ct%=p,x-=lowbit(x);
	return ct;
}
ll query(ll l,ll r){return (((r+1)*sum(s,r)%p-sum(s2,r)-l*sum(s,l-1)%p+sum(s2,l-1))%p+p)%p;}
void add(ll x,ll y){e[x].pb(y),e[y].pb(x);}
void dfs(ll x,ll f){
	fa[x]=f,sz[x]=1,d[x]=d[f]+1;
	for(auto y:e[x]) if(y!=f) dfs(y,x),sz[x]+=sz[y],son[x]=(sz[y]>sz[son[x]]?y:son[x]);
}
void dfs2(ll x,ll f){
	top[x]=f,id[x]=++ct;
	if(w[x]) qxg(id[x],id[x],w[x]);
	if(!son[x]) return;
	dfs2(son[x],f);
	for(auto y:e[x]) if(y!=fa[x]&&y!=son[x]) dfs2(y,y);
}
void addp(ll x,ll y,ll k){
	k%=p;
	while(top[x]!=top[y]){
		if(d[top[x]]<d[top[y]]) x^=y^=x^=y;
		qxg(id[top[x]],id[x],k),x=fa[top[x]];
	}
	if(d[x]>d[y]) x^=y^=x^=y;
	qxg(id[x],id[y],k);
}
void adds(ll x,ll k){qxg(id[x],id[x]+sz[x]-1,k%p);}
ll queryp(ll x,ll y){
	ll res=0;
	while(top[x]!=top[y]){
		if(d[top[x]]<d[top[y]]) x^=y^=x^=y;
		res+=query(id[top[x]],id[x]),res%=p,x=fa[top[x]];
	}
	if(d[x]>d[y]) x^=y^=x^=y;
	res+=query(id[x],id[y]),res%=p;
	return res;
}
ll querys(ll x){return query(id[x],id[x]+sz[x]-1);}
Prüfer 序列
void prufer(){
	ll x=0,leaf=0;
	for(int i=1;i<=n;i++) if(!d[i]){x=leaf=i;break;}
	for(int i=1;i<n-1;i++){
		p[i]=fa[leaf];
		if(!--d[fa[leaf]]&&fa[leaf]<x) leaf=fa[leaf];
		else{while(d[++x]);leaf=x;}
	}
}
void get_prufer(){
	ll x=0,leaf=0;while(d[++x]);leaf=x;
	for(int i=1;i<n-1;i++){
		fa[leaf]=p[i];
		if(!--d[fa[leaf]]&&fa[leaf]<x) leaf=fa[leaf];
		else{while(d[++x]);leaf=x;}
	}
	fa[leaf]=n;
}

网络流

网络最大流
void add(ll u,ll v,ll w){e[++ct]={v,h[u],w},h[u]=ct;}
bool bfs(){
	for(int i=1;i<=n;i++) dis[i]=inf;
	queue<ll> q;
	q.push(s);dis[s]=0,now[s]=h[s];
	while(!q.empty()){
		ll x=q.front();q.pop();
		for(int i=h[x];i;i=e[i].nxt)
			if(e[i].w>0&&dis[e[i].to]==inf){
				q.push(e[i].to);dis[e[i].to]=dis[x]+1,now[e[i].to]=h[e[i].to];
				if(e[i].to==t) return 1;
			}
	}
	return 0;
}
ll dfs(ll x,ll v){
	if(x==t) return v;
	ll res=0,k=0;
	for(int i=now[x];i&&v;i=e[i].nxt){
		now[x]=i;
		if(e[i].w>0&&dis[e[i].to]==dis[x]+1){
			k=dfs(e[i].to,min(v,e[i].w));
			if(!k) dis[e[i].to]=inf;
			e[i].w-=k,e[i^1].w+=k;
			res+=k,v-=k;
		}
	}
	return res;
}
ll Dinic(){
    ll ans=0;
    while(bfs()) ans+=dfs(s,inf);
	return ans;
}
<details>
<summary></summary>

/```

/```
</details>
posted @ 2024-05-20 21:33  见合  阅读(55)  评论(0编辑  收藏  举报