zoukankan      html  css  js  c++  java
  • 模板

    1.读入优化

    inline int read()  
    {  
        int ans=0,f=1;char t=getchar();  
        while(t<'0'||t>'9')   f=(t=='-'?-1:1),t=getchar();  
        while(t>='0'&&t<='9') ans=ans*10+t-'0',t=getchar();  
        return ans*f;  
    }  
    读入优化

    2.并查集

    #include<cstdio>
    #include<cstring>
    const int N=10010;
    int fa[N];
    inline int get(int x){if(fa[x]==x) return x;return fa[x]=get(fa[x]);} 
    int main()
    {
        int n,m;
        scanf("%d %d",&n,&m);
        for(int i=1;i<=n;i++) fa[i]=i;
        int flag,x,y;
        for(int i=1;i<=m;i++)
        {
            scanf("%d %d %d",&flag,&x,&y);
            if(flag==1) fa[get(x)]=get(y);
            else{if(get(x)==get(y)) printf("Y
    ");else printf("N
    ");}
        }
        return 0;
    }
    并查集

    3.最小生成树

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using std::sort;
    using std::max;
    const int N=200010;
    struct node
    {
        int v,u,p;
    }e[N];
    int fa[5050];
    bool cmp(node a,node b){return a.p<b.p;}
    int find(int x)
    {
        if(x!=fa[x]) fa[x]=find(fa[x]);
        return fa[x]; 
    }
    int main()
    {
        int n,m;
        scanf("%d %d",&n,&m);
        for(int i=1;i<=m;i++)
            scanf("%d %d %d",&e[i].v,&e[i].u,&e[i].p);
        for(int i=1;i<=n;i++) fa[i]=i;
        sort(e+1,e+1+m,cmp);
        int ans=0;
        for(int i=1;i<=m;i++)
        {
            int p=find(e[i].v),q=find(e[i].u);
            if(p!=q)
            {
    //            printf("********
    ");
                fa[p]=fa[q];
                ans+=e[i].p;
            }
        }
        printf("%d",ans);
        return 0;
    }
    最小生成树

    4.字符串哈希

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using std::sort;
    #define ull unsigned long long
    const int N=10010;
    const int M=1512;
    char map[M];
    ull sum[N],hash[M];
    int main()
    {
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%s",map+1);
            memset(hash,0,sizeof(hash));
            int len=strlen(map+1);
            for(int j=1;j<=len;j++) hash[j]=hash[j-1]*31+(map[j-1]-'a'+1);
            sum[i]=hash[len];
        }
        int ans=1;
        sort(sum+1,sum+1+n);
        for(int i=2;i<=n;i++)
        {
            if(sum[i]!=sum[i-1]) ans++;
        }
        printf("%d
    ",ans);
        return 0;
    }
    字符串哈希

    5.KMP字符串匹配

    #include<cstdio>
    #include<cstring>
    const int N=1000010;
    char a[N],b[N];
    int lena,lenb,next[N];
    void init()
    {
        int j=0;next[1]=0;
        for(int i=2;i<=lenb;i++)
        {
            while(j&&b[j+1]!=b[i]) j=next[j];
            if(b[j+1]==b[i]) j++;
            next[i]=j;
        }
    }
    void sovle()
    {
        int j=0;
        for(int i=1;i<=lena;i++)
        {
            while(j&&b[j+1]!=a[i]) j=next[j];
            if(b[j+1]==a[i]) j++;
            if(j==lenb) printf("%d
    ",i-lenb+1);
        }
    }
    int main()
    {
        scanf("%s %s",a+1,b+1);
        lena=strlen(a+1),lenb=strlen(b+1);
        init();
        sovle();
        for(int i=1;i<=lenb;i++) printf("%d ",next[i]);
        return 0;
    }
    KMP字符串匹配

    6.堆

    #include<cstdio>
    #include<cstring>
    #include<queue>
    using namespace std;
    priority_queue<int,vector<int>,greater<int> >q;
    int main()
    {
        int n;
        scanf("%d",&n);
        int pd;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&pd);
            if(pd==1) 
            {
                int v;
                scanf("%d",&v);
                q.push(v);
            }
            if(pd==2)
            {
                printf("%d
    ",q.top());
            }
            if(pd==3)
            {
                q.pop();
            }
        }
        return 0;
    }

    7.矩阵快速幂

    #include<cstdio>
    #include<cstring>
    const long long N=112;
    long long res[N][N],tt[N][N];
    long long n,m;
    const long long mod=1e9+7;  
    inline void matrix(long long a[N][N],long long b[N][N])
    {
        memset(tt,0,sizeof(tt));
        for(long long i=1;i<=n;i++)
        for(long long j=1;j<=n;j++)
        for(long long k=1;k<=n;k++)
        tt[i][j]=( tt[i][j]+(long long)a[i][k]*b[k][j]%mod)%mod;
        for(long long i=1;i<=n;i++)
        for(long long j=1;j<=n;j++)
        a[i][j]=tt[i][j];    
    }
    long long a[N][N];
    void j_poww(long long b)
    {
        for(long long i=1;i<=n;i++)
        for(long long j=1;j<=n;j++)
        scanf("%lld",&a[i][j]);
        memset(res,0,sizeof(res));
        for(long long i=1;i<=n;i++) res[i][i]=1;
        while(b)
        {
            if(b&1) matrix(res,a);
            b>>=1;    
            matrix(a,a);
        }
    }
    int main()
    {
        scanf("%lld %lld",&n,&m);
        j_poww(m);
        for(long long i=1;i<=n;i++,printf("
    "))
        for(long long j=1;j<=n;j++)
        printf("%lld ",res[i][j]);    
        return 0;
    }
    矩阵快速幂

     8.线性筛素数

    #include<cstdio>
    #include<cstring>
    const int N=1e7+12;
    int prime[N],book[N];
    int main()
    {
        int n;
        scanf("%d",&n);
        int tot=0;
        for(int i=2;i<=n;i++)
        {
            if(!book[i]) prime[++tot]=i;
            for(int j=1;j<=tot;j++)
            {
                if(i*prime[j]>n) break;
                book[i*prime[j]]=1;
                if(!i%prime[j]) break;
            }
        }
        for(int i=1;i<=tot;i++) printf("%d ",prime[i]);
        return 0; 
    }
    线性筛素数

     9.卢卡斯定理

    #include<cstdio>
    #include<cstring>
    #define ll long long
    const int N=1e6+12;
    ll aa[N<<1];
    ll p;
    inline ll max(ll a,ll b){if(a>=b)return a;return b;}
    inline ll poww(ll a,ll b)
    {
        ll ans=1;
        while(b)
        {
            if(b&1) ans=ans*a%p;
            b>>=1;a=a*a%p;
        }
        return ans;
    }
    ll C(ll n,ll m){
        if(n<m) return 0;
        if(n<p) return aa[n]*poww(aa[m],p-2)%p*poww(aa[n-m],p-2)%p;
        return C(n/p,m/p)*C(n%p,m%p)%p;
    } 
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            ll n,m;
            scanf("%lld %lld %lld",&n,&m,&p);
            memset(aa,0,sizeof(aa));
            aa[0]=1;
            for(int i=1;i<=n+m;i++) aa[i]=aa[i-1]*i%p;
            ll ans=C(n+m,n);
            printf("%lld
    ",ans);
        }
        return 0;
    }
    //C(n,m)%p=C(n/p,m/p)*C(n%p,m%p)%p
    //C(m,m+n)
    卢卡斯定理

    10.线性求逆元

    #include<cstdio>
    #include<cstring>
    #define ll long long 
    const int N=3e6+12;
    ll inv[N];
    int main()
    {
        int n,p;
        scanf("%d %d",&n,&p);
        inv[1]=1;
        printf("1
    ");
        for(int i=2;i<=n;i++)
            inv[i]=(-(p/i)*inv[p%i])%p+p,printf("%lld
    ",inv[i]);
        return 0;
    }
    线性求逆元

    11.ST表

    #include<cstdio>
    #include<cstring> 
    const int N=1e5+12;
    int map[N];
    int lg[N],f[N][27];
    inline int max(int a,int b){if(a>=b) return a;return b;}
    inline int query(int l,int r)
    {
        int t=lg[r-l+1];
        return max(f[l][t],f[r-(1<<t)+1][t]);
    }
    int main()
    {
        int n,m;
        scanf("%d %d",&n,&m);
        for(int i=1;i<=n;i++) scanf("%d",&map[i]);
        for(int i=1;i<=n;i++) f[i][0]=map[i];
        for(int j=1;j<=21;j++)
        for(int i=1;i<=n-(1<<j-1);i++)
        f[i][j]=max(f[i][j-1],f[i+(1<<j-1)][j-1]);
        lg[1]=0;
        for(int i=2;i<=n;i++) lg[i]=lg[i>>1]+1;
        int l,r;
        for(int i=1;i<=m;i++)
        {
            scanf("%d %d",&l,&r);
            printf("%d
    ",query(l,r));
        }
        return 0;
    }
    ST表

     12.文件(freopen,fclose)

    #include<cstdio>
    int main()
    {
        freopen("div.in","r",stdin);
        freopen("div.out","w",stdout);
    
    
        fclose(stdin);
        fclose(stdout);
        return 0;
    }
    freopen,fclose

     13.匈牙利算法

    #include<cstdio>
    #include<cstring>
    const int N=210;
    int map[N][N];
    int book[N];
    int tag[N];
    int n,m;
    bool find(int x)
    {
        for(int i=1;i<=m;i++)
        {
            if(map[x][i]&&(!book[i]))
            {
                book[i]=1;
                if(!tag[i]||find(tag[i]))
                {
                    tag[i]=x;
                    return true;
                }
            }
        }
        return false;
    }
    int main()
    {
        
        scanf("%d %d",&n,&m);
        int p;
        for(int i=1;i<=n;i++)
        {        
            while(true)
            {
                scanf("%d",&p);
                if(!p) break;
                else map[i][p]=1;
            }
        }
        int ans=0;
        for(int i=1;i<=n;i++)
        {
            memset(book,0,sizeof(book));
            if(find(i)) ans++;
        }
        printf("%d",ans);
        return 0;
    }
    匈牙利算法

    14.强联通分量

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using std::min;
    const int N=100010; 
    struct node{int next,to,from;}e[N];
    int first[N];
    int book[N];
    int dfn[N],low[N],stack[N],cd[N];
    int cnt=0;
    void insert(int v,int u)
    {
        e[++cnt].to=u;e[cnt].from=v;e[cnt].next=first[v];first[v]=cnt;
    }
    int tot=0,top=0,num=0;
    int size[N],color[N];
    void tarjan(int x)
    {
        dfn[x]=low[x]=++tot;
        book[x]=1;stack[++top]=x;
        for(int i=first[x];i;i=e[i].next)
        {
            if(!dfn[e[i].to]) tarjan(e[i].to),low[x]=min(low[x],low[e[i].to]);
            else if(book[e[i].to])    low[x]=min(low[x],low[e[i].to]);
        }
        if(dfn[x]==low[x])
        {
            ++num;
            while(stack[top]!=x)
            {
                book[stack[top]]=0;
                color[stack[top]]=num;
                size[num]++;
                top--;
            }
            book[x]=0;
            color[x]=num;
            size[num]++;
            top--;
        }
    }
    int main()
    {
        int n,m;
        scanf("%d %d",&n,&m);
        int v,u;
        for(int i=1;i<=m;i++)
        {
            scanf("%d %d",&v,&u);
            insert(v,u);
        }
        int ans=0;
        for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i);
        for(int i=1;i<=num;i++) if(size[i]!=1) ans++;    
        cnt=0;
        memset(first,0,sizeof(first));
        for(int i=1;i<=m;i++) 
        if(color[e[i].from]!=color[e[i].to]) cd[color[e[i].from]]++,insert(color[e[i].from],color[e[i].to]);
        ans=0;
        int aim;
        for(int i=1;i<=num;i++) if(!cd[i]) ans++,aim=i;
        if(ans!=1) printf("0");
        else printf("%d
    ",size[aim]);
        return 0;
    }
    强联通分量

     15.多重背包

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using std::max;
    const int N=217;
    int v[N],w[N],m[N];
    int dp[200010];
    int main()
    {
        int nv,n;
        scanf("%d %d",&n,&nv);
        for(int i=1;i<=n;i++)        
        {
            scanf("%d %d %d",&v[i],&w[i],&m[i]);
        }
        for(int i=1;i<=n;i++)
        {
            if(m[i]==1)
            {
                for(int j=nv;j>=v[i];j--)
                    dp[j]=max(dp[j],dp[j-v[i]]+w[i]);
            }
            else if(m[i]>=1)
            {
                if(v[i]*m[i]>=nv)
                {
                    for(int j=v[i];j<=nv;j++)
                        dp[j]=max(dp[j],dp[j-v[j]]+w[i]);
                }
                else 
                {
                    int k=1;
                    while(k<m[i])
                    {
                        for(int j=nv;j>=v[i]*k;j--)
                            dp[j]=max(dp[j],dp[j-v[i]*k]+w[i]*k);
                        m[i]-=k;
                        k<<=1;
                    }
                    if(m[i]>0) 
                        for(int j=nv;j>=v[i]*m[i];j--)
                            dp[j]=max(dp[j],dp[j-v[i]*m[i]]+w[i]*m[i]);
                }
            }
            else 
            {
                for(int j=v[i];j<=nv;j++)
                    dp[j]=max(dp[j],dp[j-v[i]]+w[i]);
            }
        }
        printf("%d",dp[nv]);
        return 0;
    }
    多重背包

    16.拓扑排序

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    using namespace std;
    const int N=200010;
    struct node
    {
        int to,next;
    }e[N];
    int first[N];
    int in[N];
    int cnt=0;
    int ans[N];
    priority_queue<int>q;
    inline void insert(int u,int v)
    {
        e[++cnt].to=v;e[cnt].next=first[u];first[u]=cnt;
    }
    int main()
    {
        int n,m;
        scanf("%d %d",&n,&m);
        int v,u;
        int tot=n+1;
        for(int i=1;i<=m;i++)
        {
            scanf("%d %d",&v,&u);
            insert(u,v);in[v]++;
        }
        for(int i=1;i<=n;i++) if(!in[i]) q.push(i);
        while(!q.empty())
        {
            int p=q.top();q.pop();
            ans[p]=--tot;
            for(int i=first[p];i;i=e[i].next)
            {
                --in[e[i].to];
                if(!in[e[i].to]) q.push(e[i].to);
            }
        }
        for(int i=1;i<=n;i++) printf("%d ",ans[i]);
        return 0;
    }
    拓扑排序
  • 相关阅读:
    《Linux网络安全技术与实现》学习
    OpenGL数据可视化
    CAPWAP简介
    《大话设计模式》学习小结
    《Python数据可视化编程实战》学习总结
    BufferedReader,缓冲输入字符流
    字符流拷贝图片,丢失数据的原因?
    reader,字符流
    BufferedInputSream和BufferedOutputSream,,,
    FileOutputSream
  • 原文地址:https://www.cnblogs.com/12fs/p/7798565.html
Copyright © 2011-2022 走看看