Educational Codeforces Round 85 (Rated for Div. 2) E Divisor Paths

链接


最短路:x->gcd(x,y)->y
然后就是一个有重复数字的错排问题,
设每种数字分别出现k1,k2,k3…kp次,并假设该错排的答案为f
那么f*k1!*k2!k3!…*kp!= ( sigma(ki) )!

#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define ls rt<<1
#define rs rt<<1|1
#define pb push_back
#define fi first
#define se second
#define yes puts("YES")
#define no puts("NO")
#define ios ios::sync_with_stdio(0);
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
typedef vector<int> VI;
const int maxn = 1e6 + 6;
const LL inf = 0x3f3f3f3f3f3f3f3f;
const int mod = 998244353;
LL qp(LL x,LL y){LL ans=1;x%=mod;while(y){if(y&1) ans=ans*x%mod;x=x*x%mod;y>>=1;}return ans;}
LL inv(LL x){return qp(x,mod-2);}


//head
vector<LL>x;
LL fac[maxn],fnv[maxn];

LL way(LL u){
   LL f=1,s=0,len=x.size();
   for(int i=0;i<len;i++){
       int p=0;
       while(u%x[i]==0) u/=x[i],p++;
       f=f*fnv[p]%mod;
       s+=p;
   }
   return f*fac[s]%mod;
}

int main(){
    fac[0]=fnv[0]=1;
    for(int i=1;i<=100000;i++) {
        fac[i]=fac[i-1]*i%mod;
        fnv[i]=qp(fac[i],mod-2);
    }

    LL d;scanf("%lld",&d);
    for(LL i=2;i*i<=d;i++){
        if(d%i==0){
            x.pb(i);
            while(d%i==0) d/=i;
        }
    }
    if(d>1) x.pb(d);
    int q;scanf("%d",&q);
    while(q--){
        LL u,v;scanf("%lld%lld",&u,&v);
        LL gcd=__gcd(u,v);
        printf("%lld\n",way(u/gcd)*way(v/gcd)%mod);
    }
}














全部评论

相关推荐

沉淀一会:1.同学你面试评价不错,概率很大,请耐心等待; 2.你的排名比较靠前,不要担心,耐心等待; 3.问题不大,正在审批,不要着急签其他公司,等等我们! 4.预计9月中下旬,安心过节; 5.下周会有结果,请耐心等待下; 6.可能国庆节前后,一有结果我马上通知你; 7.预计10月中旬,再坚持一下; 8.正在走流程,就这两天了; 9.同学,结果我也不知道,你如果查到了也告诉我一声; 10.同学你出线不明朗,建议签其他公司保底! 11.同学你找了哪些公司,我也在找工作。
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务