• 洛谷试炼场 3-5数论 3-17 倍增



    layout: post
    title: 洛谷试炼场 3-5数论 3-17 倍增
    author: "luowentaoaa"
    catalog: true
    mathjax: true
    tags:
    - 数论
    - 洛谷


    [P2152 SDOI2009]SuperGCD

    思路

    直接上python

    a=int(input())
    b=int(input())
    while a!=0:
        b%=a
        k=a
        a=b
        b=k
    print(b)
    

    P1414 又是毕业季II

    思路

    把每个数sqrt时间分解因子,然后枚举因子个数

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const ll mod=998244353;
    const int maxn=1e6+50;
    const ll inf=0x3f3f3f3f3f3f3f3fLL;
    int a[maxn];
    int num[maxn];
    int mx[maxn];
    void solve(int x){
        for(int i=1;i<=sqrt(x);i++){
            if(x%i==0){
                a[i]++;
                if(i*i!=x)a[x/i]++;
            }
        }
    }
    int main()
    {
        std::ios::sync_with_stdio(false);
        std::cin.tie(0);
        std::cout.tie(0);
        int n;
        cin>>n;
        int mp=0;
        for(int i=1;i<=n;i++){
            int aa;
            cin>>aa;
            solve(aa);
            mp=max(mp,aa);
        }
        for(int i=1;i<=n;i++){
            while(a[mp]<i)mp--;
            cout<<mp<<endl;
        }
        return 0;
    }
    

    P1313 计算系数

    思路

    直接递推

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const ll mod=10007;
    const int maxn=1e6+50;
    const ll inf=0x3f3f3f3f3f3f3f3fLL;
    ll dp[1100][1100];
    int main()
    {
        std::ios::sync_with_stdio(false);
        std::cin.tie(0);
        std::cout.tie(0);
        int a,b,k,n,m;
        cin>>a>>b>>k>>n>>m;
        dp[0][0]=1;
        for(int i=0;i<=n;i++)
        for(int j=0;j<=m;j++){
           if(i)dp[i][j]=(dp[i][j]+dp[i-1][j]*a)%mod;
           if(j)dp[i][j]=(dp[i][j]+dp[i][j-1]*b)%mod;
        }
        cout<<dp[n][m]<<endl;
        return 0;
    }
    

    P1306 斐波那契公约数 (gcd(Fn,Fm)=F(gcd(n,m)))

    思路

    只要知道gcd(fn,fm)=F(gcd(n,m))然后用一下矩阵快速幂就行

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const ll mod=1e8;
    const int maxn=1e6+50;
    const ll inf=0x3f3f3f3f3f3f3f3fLL;
    
    typedef vector<ll>vec;
    typedef vector<vec>mat;
    mat mul(mat& A,mat &B){
        mat C(A.size(),vec(B[0].size()));
        for(int i=0;i<A.size();i++)
            for(int k=0;k<B.size();k++)
            if(A[i][k])
                for(int j=0;j<B[0].size();j++)
                C[i][j]=(C[i][j]+A[i][k]*B[k][j]%mod+mod)%mod;
        return C;
    }
    mat Pow(mat A,ll n){
        mat B(A.size(),vec(A.size()));
        for(int i=0;i<A.size();i++)B[i][i]=1;
        for(;n;n>>=1,A=mul(A,A))
            if(n&1)B=mul(B,A);
        return B;
    }
    int main()
    {
        std::ios::sync_with_stdio(false);
        std::cin.tie(0);
        std::cout.tie(0);
        ll n,m;
        cin>>n>>m;
        n=__gcd(n,m);
        if(n==1){
            cout<<1<<endl;return 0;
        }
        mat solve(2,vec(2));
        solve[0][0]=1;solve[0][1]=1;
        solve[1][0]=1;solve[1][1]=0;
        mat ex(2,vec(1));
        ex[0][0]=1;ex[1][0]=1;
        solve=Pow(solve,n-2);
        solve=mul(solve,ex);
        cout<<solve[0][0]<<endl;
        return 0;
    }
    

    P1967 货车运输 (最大生成树+LCA)

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const ll mod=1e8;
    const int maxn=1e6+50;
    const ll inf=0x3f3f3f3f3f3f3f3fLL;
    int n,m;
    struct Edge{
        int from,to,w;
        bool operator <(const Edge a)const{
            return this->w>a.w;
        }
    };
    vector<Edge>edges;
    int f[maxn];
    vector<Edge>ve[maxn];
    int find(int x){
        return f[x]==x?f[x]:(f[x]=find(f[x]));
    }
    void unite(int a,int b){
        int aa=find(a),bb=find(b);
        if(aa>bb)f[aa]=bb;
        else f[bb]=f[aa];
    }
    void kruskal(){
        for(int i=0;i<=n;i++)f[i]=i;
        for(int i=0;i<2*m;i++){
            if(find(edges[i].from)!=find(edges[i].to)){
                unite(edges[i].from,edges[i].to);
                ve[edges[i].from].push_back(Edge{0,edges[i].to,edges[i].w});
                ve[edges[i].to].push_back(Edge{0,edges[i].from,edges[i].w});
            }
        }
    }
    int mi[maxn][22],fa[maxn][22],dep[maxn];
    void dfs(int now,int pre,int w,int deep){
        fa[now][0]=pre;
        mi[now][0]=w;
        if(pre==0)mi[now][0]=inf,fa[now][0]=now;
        dep[now]=deep;
        for(auto i:ve[now]){
            if(i.to==pre)continue;
            dfs(i.to,now,i.w,deep+1);
        }
    }
    void init(){
        for(int i=1;i<=20;i++)
        for(int j=1;j<=n;j++){
            int p=fa[j][i-1];
            fa[j][i]=fa[p][i-1];
            mi[j][i]=min(mi[j][i-1],mi[p][i-1]);
        }
    }
    int lca(int p,int q){
        if(dep[p]<dep[q])swap(p,q);
        int res=inf;
        for(int i=20;i>=0;i--)
            if(dep[fa[p][i]]>=dep[q])
            res=min(res,mi[p][i]),p=fa[p][i];
        if(p==q)return res;
        for(int i=20;i>=0;i--){
            if(fa[p][i]!=fa[q][i]){
                res=min(res,mi[p][i]);
                res=min(res,mi[q][i]);
                p=fa[p][i];q=fa[q][i];
            }
        }
        return min(res,min(mi[p][0],mi[q][0]));
    }
    int main()
    {
        std::ios::sync_with_stdio(false);
        std::cin.tie(0);
        std::cout.tie(0);
        cin>>n>>m;
        for(int i=1;i<=m;i++){
            int a,b,c;
            cin>>a>>b>>c;
            edges.push_back(Edge{a,b,c});
            edges.push_back(Edge{b,a,c});
        }
        sort(edges.begin(),edges.end());
        kruskal();
        for(int i=1;i<=n;i++){
            if(f[i]==i){
                dfs(i,0,0,0);
            }
        }
        init();
        int q;cin>>q;
        while(q--){
            int x,y;
            cin>>x>>y;
            if(find(x)!=find(y))cout<<-1<<endl;
            else cout<<lca(x,y)<<endl;
        }
        return 0;
    }
    

    P1613 跑路 (倍增+floyd)

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const ll mod=998244353;
    const int maxn=1e6+50;
    const ll inf=0x3f3f3f3f3f3f3f3fLL;
    int d[100][100],n,m;
    bool ok[100][100][100];
    
    int main()
    {
        std::ios::sync_with_stdio(false);
        std::cin.tie(0);
        std::cout.tie(0);
        memset(d,inf,sizeof(d));
        cin>>n>>m;
        while(m--){
            int x,y;
            cin>>x>>y;
            d[x][y]=1;
            ok[x][y][0]=true;
        }
        for(int log=1;log<=50;log++)
            for(int k=1;k<=n;k++)
            for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
        if(ok[i][k][log-1]&&ok[k][j][log-1]){
            ok[i][j][log]=true;
            d[i][j]=1;
        }
        for(int k=1;k<=n;k++)
        for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
        if(d[i][j]>(d[i][k]+d[k][j])){
            d[i][j]=d[i][k]+d[k][j];
        }
        cout<<d[1][n]<<endl;
        return 0;
    }
    
  • 相关阅读:
    Linux系统配置(防火墙)
    读取数据库中的json格式的字符串数据时cJSON解析后总会出现很多反斜杠的问题
    std::map添加一个类类型
    RabbitVCS SVN:提交失败,工作副本已经锁定
    Qt输入法
    二叉树是逻辑结构 与定时 小顶堆
    Kettle 的 安装 及 简单使用
    删除 canal 实例
    /opt/module/canal/conf/canal.properties
    Mac VMware 虚拟机 对应 win 的三种 网络模式
  • 原文地址:https://www.cnblogs.com/luowentao/p/10354921.html
Copyright © 2020-2023  润新知