You are given a positive integer D. Let’s build the following graph from it:c++
each vertex is a divisor of D (not necessarily prime, 1 and D itself are also included);
two vertices x and y (x>y) have an undirected edge between them if x is divisible by y and xy is a prime;
the weight of an edge is the number of divisors of x that are not divisors of y.
For example, here is the graph for D=12:web
Edge (4,12) has weight 3 because 12 has divisors [1,2,3,4,6,12] and 4 has divisors [1,2,4]. Thus, there are 3 divisors of 12 that are not divisors of 4 — [3,6,12].svg
There is no edge between 3 and 2 because 3 is not divisible by 2. There is no edge between 12 and 3 because 123=4 is not a prime.ui
Let the length of the path between some vertices v and u in the graph be the total weight of edges on it. For example, path [(1,2),(2,6),(6,12),(12,4),(4,2),(2,6)] has length 1+2+2+3+1+2=11. The empty path has length 0.spa
So the shortest path between two vertices v and u is the path that has the minimal possible length.code
Two paths a and b are different if there is either a different number of edges in them or there is a position i such that ai and bi are different edges.orm
You are given q queries of the following form:xml
v u — calculate the number of the shortest paths between vertices v and u.
The answer for each query might be large so print it modulo 998244353.token
The first line contains a single integer D (1≤D≤1015) — the number the graph is built from.ip
The second line contains a single integer q (1≤q≤3⋅105) — the number of queries.
Each of the next q lines contains two integers v and u (1≤v,u≤D). It is guaranteed that D is divisible by both v and u (both v and u are divisors of D).
Print q integers — for each query output the number of the shortest paths between the two given vertices modulo 998244353.
对于两个点之间的最短路径就是一直除或者一直乘,除的顺序和乘的顺序是不影响总权重的。
a->b->c的总权重为a的权重-b的权重+b的权重-c的权重…
选择的顺序经过组合数学来求…
#include<bits/stdc++.h> #define ll long long using namespace std; const int maxn=1e5+5; const int inf=0x3f3f3f3f; const int mod=998244353; ll ans[maxn],fac[maxn],a[maxn]; ll pow_(ll a,ll b){ a%=mod; ll ans=1; while(b){ if(b&1)ans=(ans*a)%mod; a=(a*a)%mod; b>>=1; } return ans; } ll gcd(ll a,ll b){ return b?gcd(b,a%b):a; } ll C(ll n,ll m){ return (fac[n]*pow_(fac[n-m]*fac[m],mod-2))%mod; } ll cal(ll x){ ll ans=1; int cnt=0,all=0; for(ll i=2;i*i<=x;++i){ int num=0; while(x%i==0){ ++num; x/=i; } all+=num; if(num)a[++cnt]=num; } if(x>1||cnt==0)a[++cnt]=1,++all; for(int i=1;i<=cnt;++i){ ans=(ans*C(all,a[i]))%mod; all-=a[i]; } return ans; } int main() { ll d,u,v,q; map<ll,ll>mp; scanf("%lld %lld",&d,&q); fac[0]=fac[1]=1; for(int i=2;i<maxn;++i)fac[i]=(fac[i-1]*i)%mod; while(q--){ scanf("%lld %lld",&u,&v); ll g=gcd(u,v); u/=g,v/=g; if(mp[u]==0)mp[u]=cal(u); if(mp[v]==0)mp[v]=cal(v); printf("%lld\n",(mp[u]*mp[v]+mod)%mod); } return 0; }