E. Divisor Paths(一个比较有意思的题(数论?思维?细节?))

题目链接:https://codeforces.com/contest/1334/problem/E

题目大意

给你一个数n   数的每个因子是一张图上的点,点相连的规则是x,y  (x>y)  x/y=质数

现在有好多次询问  每次给你一个a,b问有多少条最短路可以从a到b

 

因为每次只能除一个质数或乘一个质数,所以很容易想到a先到gcd(a,b) 然后再到b,每个质数为一步,那么a到gcd(a,b)假设有m种质数,每种有cnt[i]个,那么排列组合的种数就是

sum!/(cnt[i]!*cnt[i-1]!*....)

还需要预处理n的所有质因子,因为n的每个因子都是由这些质因子组合而来的

AC代码:

#include
using namespace std;
const int N=2e5+7;
typedef long long ll;
const ll mod=998244353;

ll gcd(ll a,ll b)
{
if(a==0)
{
return b;
}else
{
return gcd(b % a,a);
}
}
ll f[1007];
ll kk[1007];
ll power(ll a,ll b)///a是底数,b是次幂
{
 ll ans=1;
 for(;b!=0;b/=2)
 {
  if(b&1) ans=(long long)ans*a%mod;
  a=(long long)a*a%mod;
 }
 return ans;
}

int main()
{
    ios::sync_with_stdio(false);
    ll n;
    cin>>n;
    vectors;
    
    f[0]=1;
    for(int i=1;i<=1000;i++) f[i]=f[i-1]*i%mod;///阶乘mod
    kk[1]=1;
    for(int i=2;i<=1000;i++) kk[i]=kk[i-1]*power(i,mod-2)%mod;///阶乘逆元
    //cout<>m;
    while(m--)
    {
        ll x1,x2;cin>>x1>>x2;
        ll d=gcd(x1,x2);
        x1=x1/d;
        x2=x2/d;
        //cout<

 

你可能感兴趣的:(算法)