题解 CF1334E 【Divisor Paths】
GavinZheng · · 题解
我们发现,每次走过一条路径都是减少/增加一个质因子。而且边权是减少/增加一个质因子后减少/增加的因数个数。那么显然有:
又因为
那么算法就很显然了。我们先分解
那么
P.S. 有个小问题,就是为什么不走
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<vector>
#include<queue>
#define vi vector<int>
#define pb push_back
#define mk make_pair
#define pii pair<int,int>
#define rep(i,a,b) for(int i=(a),i##end=(b);i<=i##end;i++)
#define fi first
#define se second
typedef long long ll;
using namespace std;
const int maxn=3e5+100;
const int mod=998244353;
ll d,q;
ll prime[maxn],prime_cnt,frac[maxn];
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
int ksm(ll num,ll t) {
ll res=1;num%=mod;
for(;t;t>>=1,num=num*num%mod) {
if(t&1)res=num*res%mod;
}
return res%mod;
}
ll solve(ll u) {
ll a=1,b=1,tot=0;//分子分母
rep(i,1,prime_cnt) {
ll cnt=0;while(u%prime[i]==0)u/=prime[i],cnt++;
b=b*frac[cnt]%mod;tot+=cnt;
}
a=frac[tot];
return a*ksm(b,mod-2)%mod;
}
int main() {
ios::sync_with_stdio(0);
cin>>d>>q;
frac[0]=frac[1]=1;//预处理阶乘
rep(i,2,100)frac[i]=frac[i-1]*i%mod;
ll tmp=d;
for(ll i=2;i*i<=d;i++) {
if(tmp%i==0)prime[++prime_cnt]=i;
while(tmp%i==0)tmp/=i;
}
if(tmp>1)prime[++prime_cnt]=tmp;
rep(i,1,q) {
ll u,v;cin>>u>>v;ll g=gcd(u,v);
cout<<solve(u/g)*solve(v/g)%mod<<endl;
}
return 0;
}