这里贴出各种算法与数据结构的模板。这篇文章将持续更新。
//留坑
int read()
{
int t=0,p=1;
for(ch=getchar();ch<'0' || ch>'9';ch=getchar())
if(ch=='-') p=-1;
for(;'0'<=ch && ch<='9';ch=getchar()) t=t*10+ch-'0';
return t*p;
}
void find(int v,int from,int tot)
{
sum[v]=1;
int maxi=0;
for(int i=last[v];i;i=next[i])
{
int u=to[i];
if(u==from || bz[u]) continue;
find(u,v,tot);
sum[v]+=sum[u];
maxi=max(maxi,sum[u]);
}
int t=max(maxi,tot-sum[v]);
if(t<=val) val=t,root=v;
}
int lca(int u,int v)
{
if(deep[u]<deep[v]) swap(u,v);
fd(i,int(log2(deep[u])),0)
if(deep[f[u][i]]>=deep[v]) u=f[u][i];
fd(i,int(log2(deep[u])),0)
if(f[u][i]!=f[v][i]) u=f[u][i],v=f[v][i];
if(u!=v) return f[u][0];
return u;
}
void tarjan(int v)
{
stack[++top]=v;
low[v]=dfn[v]=++now;
bz[v]=vis[v]=1;
for(int i=last[v];i;i=next[i])
{
int u=to[i];
if(dfn[u]==0)
{
tarjan(u);
low[v]=min(low[v],low[u]);
}
else
if(vis[u] && dfn[u]<low[v]) low[v]=dfn[u];
}
if(low[v]==dfn[v])
{
long long t=0;
do
{
vis[stack[top--]]=0;
t++;
}
while(stack[top+1]!=v);
ans+=t*(t-1)/2;
}
}
int aug(int v,int flow)
{
if(v==T) return flow;
int minh=n+1;
for(int i=last[v];i!=0;i=next[i])
{
int u=to[i];
if(c[v][u]>0)
{
if(h[v]==h[u]+1)
{
int f=aug(u,min(flow,c[v][u]));
if(f>0)
{
c[v][u]-=f;
c[u][v]+=f;
return f;
}
if(h[S]>n) return 0;
}
minh=min(minh,h[u]+1);
}
}
if(--vh[h[v]]==0) h[S]=n+1;
h[v]=minh;
vh[h[v]]++;
return 0;
}
void gcd(ll a,ll b,ll &x,ll &y)
{
if(b==0)
{
x=1,y=0;
return;
}
ll xx,yy;
gcd(b,a%b,xx,yy);
x=yy,y=xx-a/b*yy;
}
ll phi(int n)
{
ll t=n;
for(int i=2;i*i<=n;i++)
if(!(n%i))
{
t=t/i*(i-1);
while(!(n%i)) n/=i;
}
if(n>1) t=t/n*(n-1);
return num;
}
fo(i,1,n)
{
fo(j,i+1,n) a[i][j]/=a[i][i];
b[i]/=a[i][i];
a[i][i]=1;
fo(j,i+1,n)
{
fo(k,i+1,n) a[j][k]-=a[j][i]*a[i][k];
b[j]-=a[j][i]*b[i];
a[j][i]=0;
}
}
fd(i,n,1)
{
fo(j,1,i-1)
{
b[j]-=a[j][i]*b[i];
a[j][i]=0;
}
}
fo(i,1,n) printf("%.2lf ",b[i]);
void pre(int n)
{
mu[1]=1;
fo(i,2,n)
{
if(!bz[i])
{
mu[i]=-1;
pri[++pri[0]]=i;
}
fo(j,1,pri[0])
{
int t=i*pri[j];
if(t>n) break;
bz[t]=1;
if(i%pri[j]==0)
{
mu[t]=0;
break;
}
mu[t]=-mu[i];
}
}
}
ll Sk(ll n)
{
f[0]=n;
fo(i,1,k)
{
f[i]=1;
fo(j,n-i+1,n+1)
if(j%(i+1)) f[i]=qmul(f[i],j);
else f[i]=qmul(f[i],j/(i+1));
fo(j,0,i-1)
(f[i]=f[i]-qmul(ss[i][j],f[j])+mo)%mo;
}
return f[k];
}
ss 表示带符号第一类斯特林数。其递推公式如下:
ss[0][0]=1;
fo(i,1,k)
fo(j,1,i) ss[i][j]=(ss[i-1][j-1]-(i-1)*ss[i-1][j]%mo+mo)%mo;
void get(char *s)
{
int len=strlen(s+1),j=0;
fo(i,2,len)
{
while(j && s[i]!=s[j+1]) j=f[j];
f[i]=s[i]==s[j+1]?(++j):(j=0);
}
}
int KMP(char *s1,char *s2)
{
get(s2);
int j=0,ans=0,len1=strlen(s1+1),len2=strlen(s2+1);
fo(i,1,len1)
{
while(j && s1[i]!=s2[j+1]) j=f[j];
if(s1[i]==s2[j+1]) j++;
if(j==len2) ans++;
}
return ans;
}
void DA()
{
int mx=0;
fo(i,1,n) mx=max(mx,wv[i]=x[i]=s[i]-'a'+1);
fill(ws,ws+mx+1,0);
fo(i,1,n) ws[wv[i]]++;
fo(i,1,mx) ws[i]+=ws[i-1];
fd(i,n,1) SA[ws[wv[i]]--]=i;
for(int len=1;len<=n;len*=2)
{
int m=0;
fo(i,n-len+1,n) y[++m]=i;
fo(i,1,n)
if(SA[i]>len) y[++m]=SA[i]-len;
mx=0;
fo(i,1,n) mx=max(mx,wv[i]=x[y[i]]);
fill(ws,ws+mx+1,0);
fo(i,1,n) ws[wv[i]]++;
fo(i,1,mx) ws[i]+=ws[i-1];
fd(i,n,1) SA[ws[wv[i]]--]=y[i];
fo(i,1,n) y[i]=x[i],x[i]=0;
x[SA[m=1]]=1;
fo(i,2,n) x[SA[i]]=cmp(SA[i-1],SA[i],len)?m:++m;
if(m==n) break;
}
fo(i,1,n) rank[SA[i]]=i;
}
int maxi=0,mid,ans=0;
for(int i=1;i<=len;i++)
{
f[i]=1;
if(maxi>i) f[i]=min(f[2*mid-i],maxi-i);
while(s2[i+f[i]]==s2[i-f[i]]) f[i]++;
if(f[i]+i>maxi)
{
maxi=f[i]+i;
mid=i;
}
ans=max(ans,f[i]-1);
}