洛谷试炼场 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;
}

猜你喜欢

转载自www.cnblogs.com/luowentao/p/10354921.html