板子合集
以下是这位蒟蒻的板子合集(不全)
欢迎大家来看看 24oi 不知道第几届 手速大赛 垫底选手的赛时代码(
快读快写:
点击查看代码
inl int read(){
int x=0,f=1;char c=gc();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=gc();}
while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=gc();}
return x*f;
}
inl void write(int x){
if(x<0){pc('-');x=-x;}
if(x>9)write(x/10);
pc(x%10+'0');
}
inl void writei(int x){write(x);pc(' ');}
inl void writel(int x){write(x);pc('\n');}
最小生成树:
点击查看代码
int n,m,k,ans,fa[N];
inl int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
struct edge{
int u,v,c;
friend bool operator<(edge a,edge b){return a.c<b.c;}
}e[N];
signed main(){
n=read();m=read();
for(int i=1;i<=n;i++)fa[i]=i;
for(int i=1;i<=m;i++)
e[i]={read(),read(),read()};
sort(e+1,e+m+1);
for(int i=1;i<=m;i++){
if(k==n-1)break;
int x=e[i].u,y=e[i].v;
int fx=find(x),fy=find(y);
if(fx==fy)continue;
fa[fx]=fy;ans+=e[i].c;
k++;
}
if(k^(n-1)){puts("orz");return 0;}
writel(ans);
return 0;
}
单调队列:
点击查看代码
int n,k,a[N],dq[N],h=1,t;
signed main(){
n=read();k=read();
for(int i=1;i<=n;i++)a[i]=read();
for(int i=1;i<=n;i++){//取min
while(h<=t&&dq[h]<=i-k)h++;
while(h<=t&&a[dq[t]]>=a[i])t--;
dq[++t]=i;
if(i>=k)writei(a[dq[h]]);
}puts("");h=1,t=0;
for(int i=1;i<=n;i++){//取max
while(h<=t&&dq[h]<=i-k)h++;
while(h<=t&&a[dq[t]]<=a[i])t--;
dq[++t]=i;
if(i>=k)writei(a[dq[h]]);
}
return 0;
}
KMP:
点击查看代码
string s,ss;
int nxt[N];
signed main(){
cin>>s>>ss;
int len1=s.size(),len2=ss.size();
for(int i=1,j=0;i<len2;i++){
while(j&&ss[i]^ss[j])j=nxt[j];
if(ss[i]==ss[j])nxt[i+1]=++j;
}
for(int i=0,j=0;i<len1;i++){
while(j&&s[i]^ss[j])j=nxt[j];
if(s[i]==ss[j])j++;
if(j==len2){writel(i-len2+2);j=nxt[j];}
}
for(int i=1;i<=len2;i++)
writei(nxt[i]);
return 0;
}
单源最短路(dij):
点击查看代码
inl void dij(int s){
memset(dis,0x3f,sizeof dis);
priority_queue<pair<int,int>,vector<pair<int,int>>,greater<pair<int,int>>>q;
q.push({0,s});dis[s]=0;
while(!q.empty()){
int x=q.top().second;q.pop();
if(vis[x])continue;vis[x]=1;
for(int i=head[x];i;i=nxt[i]){
int y=to[i],c=w[i];
if(dis[y]>dis[x]+c){
dis[y]=dis[x]+c;
q.push({dis[y],y});
}
}
}
}
线段树2(区间加乘):
点击查看代码
int n,m,q,a[N],x,y,k,op;
namespace SGT{
int s[N<<2],tag1[N<<2],tag2[N<<2];
inl void pushup(int k){return s[k]=(s[ls]+s[rs])%m,void();}
inl void adt(int k,int l,int r,int v1,int v2){
s[k]=(s[k]*v2%m+(r-l+1)*v1%m)%m;
tag1[k]=(tag1[k]*v2%m+v1)%m;
tag2[k]=tag2[k]*v2%m;
}
inl void pushdown(int k,int l,int r){
adt(ls,l,mid,tag1[k],tag2[k]);
adt(rs,mid+1,r,tag1[k],tag2[k]);
tag1[k]=0,tag2[k]=1;
}
inl void build(int k,int l,int r){
tag2[k]=1;
if(l==r)return s[k]=a[l],void();
build(ls,l,mid);build(rs,mid+1,r);
pushup(k);
}
void modify(int k,int l,int r,int x,int y,int v1,int v2){
if(x<=l&&r<=y)return adt(k,l,r,v1,v2);
pushdown(k,l,r);
if(x<=mid)modify(ls,l,mid,x,y,v1,v2);
if(y>mid)modify(rs,mid+1,r,x,y,v1,v2);
pushup(k);
}
int query(int k,int l,int r,int x,int y){
if(x<=l&&r<=y)return s[k];
pushdown(k,l,r);
int ans=0;
if(x<=mid)ans=(ans+query(ls,l,mid,x,y))%m;
if(y>mid)ans=(ans+query(rs,mid+1,r,x,y))%m;
return ans;
}
}
signed main(){
n=read();q=read();m=read();
for(int i=1;i<=n;i++)a[i]=read();
SGT::build(1,1,n);
while(q--){
op=read();
if(op==1){
x=read();y=read();k=read();
SGT::modify(1,1,n,x,y,0,k);
}
if(op==2){
x=read();y=read();k=read();
SGT::modify(1,1,n,x,y,k,1);
}
if(op==3){
x=read();y=read();
writel(SGT::query(1,1,n,x,y));
}
}
return 0;
}
spfa判负环(差分约束):
点击查看代码
int n,m,u,v,c;
int head[N],nxt[N],to[N],w[N],cntt;
inl void add(int u,int v,int c){
nxt[++cntt]=head[u];
to[cntt]=v;w[cntt]=c;
head[u]=cntt;
}
int dis[N],vis[N],cnt[N];
inl bool spfa(int s){
queue<int>q;
memset(dis,0x3f,sizeof dis);
q.push(s);dis[s]=0;
while(!q.empty()){
int x=q.front();q.pop();vis[x]=0;
for(int i=head[x];i;i=nxt[i]){
int y=to[i],c=w[i];
if(dis[y]>dis[x]+c){
dis[y]=dis[x]+c;
cnt[y]=cnt[x]+1;
if(cnt[y]>n)return 0;
if(!vis[y]){q.push(y);vis[y]=1;}
}
}
}
return 1;
}
signed main(){
n=read();m=read();
for(int i=1;i<=m;i++){
u=read();v=read();c=read();
add(v,u,c);
}
for(int i=1;i<=n;i++)add(n+1,i,0);
if(!spfa(n+1))puts("NO");
else for(int i=1;i<=n;i++)writei(dis[i]);
return 0;
}
tarjan(缩点):
点击查看代码
int n,m,a[N],u[N],v[N],c,ans;
int head[N],nxt[N],to[N],cnt;
inl void add(int u,int v){
nxt[++cnt]=head[u];
to[cnt]=v;
head[u]=cnt;
}
stack<int>st;
int vis[N],dfn[N],low[N],dfs_clock,idx[N],id,sum[N],f[N];
inl void tarjan(int x){
dfn[x]=low[x]=++dfs_clock;
st.push(x);vis[x]=1;
for(int i=head[x];i;i=nxt[i]){
int y=to[i];
if(!dfn[y]){
tarjan(y);
low[x]=min(low[x],low[y]);
}else if(vis[y]){
low[x]=min(low[x],dfn[y]);
}
}
if(dfn[x]^low[x])return;id++;int y;
do{
y=st.top();st.pop();
vis[y]=0;idx[y]=id;
sum[id]+=a[y];
}while(y^x);
}
inl void init(){
memset(head,0,sizeof head);
memset(nxt,0,sizeof nxt);
cnt=0;
}
signed main(){
n=read();m=read();
for(int i=1;i<=n;i++)a[i]=read();
for(int i=1;i<=m;i++){
u[i]=read();v[i]=read();
add(u[i],v[i]);
}
for(int i=1;i<=n;i++)if(!dfn[i])tarjan(i);
for(int i=1;i<=id;i++)f[i]=sum[i];
init();
for(int i=1;i<=m;i++){
if(idx[u[i]]==idx[v[i]])continue;
add(idx[u[i]],idx[v[i]]);
}
for(int x=id;x;x--){
for(int i=head[x];i;i=nxt[i]){
int y=to[i];
f[y]=max(f[y],f[x]+sum[y]);
}
}
for(int i=1;i<=id;i++)ans=max(ans,f[i]);
writel(ans);
return 0;
}
trie树:
点击查看代码
int tt,n,m,t[N][65],idx,cnt[N];
char s[N];
inl int getnum(int x){
if(x>='0'&&x<='9')return x-'0'+1;
if(x>='a'&&x<='z')return x-'a'+11;
return x-'A'+37;
}
inl void add(char *c){
int len=strlen(c),p=0;
for(int i=0;i<len;i++){
int x=getnum(c[i]);
if(!t[p][x])t[p][x]=++idx;
p=t[p][x];cnt[p]++;
}
}
inl int query(char *c){
int len=strlen(c),p=0;
for(int i=0;i<len;i++){
int x=getnum(c[i]);
if(!t[p][x])return 0;
p=t[p][x];
}
return cnt[p];
}
inl void init(){
for(int i=0;i<=idx;i++){
cnt[i]=0;
memset(t[i],0,sizeof(t[i]));
}idx=0;
}
signed main(){
tt=read();
while(tt--){
init();
n=read();m=read();
while(n--){scanf("%s",s);add(s);}
while(m--){scanf("%s",s);writel(query(s));}
}
return 0;
}
st表:
点击查看代码
int n,m,st[N][22],l,r,Log[N];
signed main(){
n=read();m=read();
for(int i=1;i<=n;i++)st[i][0]=read();
for(int j=1;j<=20;j++)
for(int i=1;i+(1<<j)-1<=n;i++)
st[i][j]=max(st[i][j-1],st[i+(1<<j-1)][j-1]);
Log[0]=-1;
for(int i=1;i<=n;i++)Log[i]=Log[i>>1]+1;
while(m--){
l=read();r=read();
int k=Log[r-l+1];
writel(max(st[l][k],st[r-(1<<k)+1][k]));
}
return 0;
}
矩阵加速(Fibonacci数列):
点击查看代码
int n;
struct node{
int a[3][3];
}x;
inl void empty(node &x){
for(int i=1;i<=2;i++)
for(int j=1;j<=2;j++)
x.a[i][j]=0;
}
inl void init(node &x){
for(int i=1;i<=2;i++)
for(int j=1;j<=2;j++)
x.a[i][j]=(i==j);
}
node operator*(node x,node y){
node ans;empty(ans);
for(int i=1;i<=2;i++)
for(int j=1;j<=2;j++)
for(int k=1;k<=2;k++)
ans.a[i][j]=(ans.a[i][j]+x.a[i][k]*y.a[k][j]%mod)%mod;
return ans;
}
inl void qpow(node &a,int b){
node ans;init(ans);
while(b){
if(b&1)ans=ans*a;
a=a*a;
b>>=1;
}
a=ans;
}
signed main(){
n=read();
if(n<=2){writel(1);return 0;}
x.a[1][2]=x.a[2][1]=x.a[2][2]=1;
qpow(x,n-2);
writel((x.a[1][2]+x.a[2][2])%mod);
return 0;
}
exgcd(同余方程):
点击查看代码
int n,a,b;
void exgcd(int a,int b,int &x,int &y){
if(!b)return x=1,y=0,void();
exgcd(b,a%b,y,x);
y-=(a/b)*x;
}
signed main(){
a=read();b=read();
int x,y;
exgcd(a,b,x,y);
writel((x%b+b)%b);
return 0;
}
选课是树形背包板子就不放了
lca(倍增版):
点击查看代码
int n,m,u,v,f[N][22],dep[N],s;
int head[N],nxt[N],to[N],cnt;
inl void add(int u,int v){
nxt[++cnt]=head[u];
to[cnt]=v;
head[u]=cnt;
}
inl void dfs(int x,int fa){
f[x][0]=fa;dep[x]=dep[fa]+1;
for(int i=1;i<=20;i++)f[x][i]=f[f[x][i-1]][i-1];
for(int i=head[x];i;i=nxt[i]){
int y=to[i];
if(y==fa)continue;
dfs(y,x);
}
}
inl int get_lca(int x,int y){
if(dep[x]<dep[y])swap(x,y);
for(int i=20;~i;i--){
if(dep[f[x][i]]<dep[y])continue;
x=f[x][i];
}
if(x==y)return x;
for(int i=20;~i;i--){
if(f[x][i]==f[y][i])continue;
x=f[x][i];y=f[y][i];
}
return f[x][0];
}
signed main(){
n=read();m=read();s=read();
for(int i=1;i<=n-1;i++){
u=read();v=read();
add(u,v);add(v,u);
}dfs(s,0);
while(m--){
u=read(),v=read();
writel(get_lca(u,v));
}
return 0;
}
欧拉路径:
点击查看代码
int n,m,s,u,v,c,in[N],out[N],k=1,flag,head[N];
vector<int>G[N];
stack<int>st;
inl void dfs(int x){
for(int i=head[x];i<G[x].size();i=head[x]){
head[x]=i+1;
dfs(G[x][i]);
}
st.push(x);
}
signed main(){
n=read();m=read();
for(int i=1;i<=m;i++){
u=read();v=read();
G[u].push_back(v);
out[u]++;in[v]++;
}
k=1;
for(int i=1;i<=n;i++){
if(out[i]-in[i]==1){
flag++;k=i;
}else if(in[i]-out[i]==1)
flag++;
}
if(flag&&(flag^2)){puts("No");return 0;}
for(int i=1;i<=n;i++)sort(G[i].begin(),G[i].end());
dfs(k);
while(!st.empty()){writei(st.top());st.pop();}
return 0;
}