题目链接:https://ac.nowcoder.com/acm/contest/5674/E
思路:
对于x,y的公共质因子p来说,
如果在x的唯一分解中的幂次为m,在y的唯一分解中的幂次为n
那么当mi >= nj的时候, 即j <= mi/n的时候,gcd的p的幂次为nj
当m
i < nj的时候,即j>= mi/n的时候,gcd的p的幂次为mi
枚举i便可以确定m
i/n
对于大于mi/n的j来说,p的幂次的总和就是:mi
(d-mi/n)
对于小于等于m*i/n的j来说,p的幂次的总和就是:n
(c+c+1+c+2+...+m*i/n)
鉴于p的幂次最后会很大,可能会爆ll,可以使用欧拉降幂
另外,如果刚好可以整除,对于除数,可以不用取逆元。
由于p=998244353是个质数,phi(p)=p-1,因此a^b%mod和a^(b%(mod-1))相等
图片说明

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod  = 998244353;

int e[2][500];
vector<int> fac;

ll q_pow(ll a, ll b){
    ll ans = 1;
    while(b > 0){
        if(b & 1){
            ans = ans * a % mod;
        }
        a = a * a % mod;
        b >>= 1; 
    } 
    return ans;
}

void Factor(int n)
{
    for(int i = 2; i*i <= n; i++)
    {
        if(n % i == 0)
        {
            fac.push_back(i);
            while(n%i == 0) n/=i;
        }
    }
    if(n>1) fac.push_back(n);
}

void cont(int x, int p)
{
    for(int i = 0; i < fac.size(); i++)
    {
        e[p][i] = 0;
        while(x % fac[i] == 0)
        {
            e[p][i]++;
            x/=fac[i];
        }
    }
}

ll solve(int a, int b, int c, int d, int p)
{
    ll res = 0 , ans=1;
    for(int i = a; i <= b; i++)
    {
        ll t = 1LL*i*e[0][p];
        ll w = t/e[1][p];
        if(w < c)
        {
            res = (res + 1LL*(d-c+1)*t)%(mod-1);
            continue;
        }
        if(w >= d)
        {
            res = (res + 1LL*(c+d)*(d-c+1)/2*e[1][p])%(mod-1);
            continue;
        }
        ll u = 1LL*e[1][p]*(c+w)*(w-c+1)/2;
        res = (res + t*(d-w) + u) % (mod-1); 
    }
    ans = ans*q_pow(1LL*fac[p], res%(mod-1))%mod;
    return ans;
}

int main()
{
    int a, b, c, d, x, y;
    scanf("%d%d%d%d%d%d",&a,&b,&c,&d,&x,&y);
    int g = __gcd(x, y);
    Factor(g);
    cont(x, 0);
    cont(y, 1);
    ll res = 1;
    for(int i = 0; i < fac.size(); i++) {
        ll tmp = solve(a, b, c, d, i);
        res = (res*tmp%mod + mod)%mod;
    }
    printf("%lld\n",res);
    return 0;
}