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>
弱小与无知不是生存的障碍,傲慢才是。--《三体》