zoukankan      html  css  js  c++  java
  • 数论+思维+组合数学+奇妙结论——cf1334E

    /*
    题意:给定D,用D的因子构造一张图
    因子u,v之间有边:u/v是质数,边权是 u的因子数-v的因子数,
    路径长度=边权之和
    给定 u,v,求u,v之间最短路径的条数
    怎么确定最短路径
        u->v,每步等价于u乘以一个质数或除以一个质因子,这条最短路肯定经过gcd(u,v)
        那么原问题转化为 u->gcd(u,v)的路径条数*gcd(u,v)->v的最短路径条数
    怎么求u->gcd(u,v)的最短路径数量?
        u必须把多出来的那部分质因子给去掉
        结论:不管按什么方式去掉质因子,最后的路径长度是不会变的(我也不知道为什么会有这个结论..看规律是这样的)
        所以问题转化为有多少种去掉质因子的方式:就是个全排列 
    */
    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long 
    #define mod 998244353
    #define N 40000005
    
    ll prime[3000005],m,F[100005],inv[100005];
    bool vis[N];
    ll Pow(ll a,ll b){
        ll res=1;
        while(b){
            if(b%2)res=res*a%mod;
            b>>=1;a=a*a%mod;
        }
        return res;
    } 
    ll D,u,v;
    void init(){
        F[0]=1;
        for(int i=1;i<=100000;i++){
            F[i]=F[i-1]*i%mod;
            inv[i]=Pow(F[i],mod-2);
        }
        for(ll i=2;i*i<=D;i++)if(D%i==0){
            prime[++m]=i;
            while(D%i==0)
                D/=i;    
        }
        if(D>1)prime[++m]=D;
        sort(prime+1,prime+1+m);
        
    }
    
    
    ll p[1000005],mm,c[1000005];
    void divide(ll x){
        mm=0;
        for(int i=1;i<=m;i++){
            if(prime[i]*prime[i]>x)break;
            if(x%prime[i]==0){
                p[++mm]=prime[i];
                c[mm]=0;
                while(x%prime[i]==0)
                    ++c[mm],x/=prime[i];
            }
        }
        if(x>1){
            p[++mm]=x;
            c[mm]=1;
        }
    }
    
    ll solve(ll x){
        divide(x);
        ll res=1,sum=0;
        for(int i=1;i<=mm;i++)sum+=c[i];
        res=F[sum];
        for(int i=1;i<=mm;i++)
            res=res*inv[c[i]]%mod;
        return res;
    }
    
    int main(){
        cin>>D;
        init();
        int q;cin>>q;
        while(q--){
            scanf("%lld%lld",&u,&v);
            ll d=__gcd(u,v);
            ll ans=1;
            u/=d;v/=d;
            ans=ans*solve(u)%mod;
            ans=ans*solve(v)%mod;
            cout<<ans<<'
    ';
        }
    }
  • 相关阅读:
    Day10
    Python pyspider 安装与开发
    深入理解ES6之《块级作用域绑定》
    深入理解ES6之《扩展对象》
    这些特效对于学习前端我们很有用
    算法之旅 | 选择排序法
    JavaScript读取剪贴板中的表格生成图片
    深入理解ES6之《ES7》
    深入理解ES6之《用模块封装代码》
    php://input,$_POST,$HTTP_RAW_POST_DATA区别
  • 原文地址:https://www.cnblogs.com/zsben991126/p/12763272.html
Copyright © 2011-2022 走看看