板子合集

以下是这位蒟蒻的板子合集(不全)

欢迎大家来看看 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;
}
posted @ 2023-10-20 07:45  xiang_xiang  阅读(27)  评论(0编辑  收藏  举报