牛客多校第九场 Groundhog Chasing Death(GCD,素数)

牛客多校第九场 Groundhog Chasing Death(GCD,素数)_第1张图片
思路:
将x,y的公有素因子找出了,最多10来个。
然后枚举x的指数,再分别考虑每个素因子,可以得到y对应指数要到多少才会被算到。

#include 
#include 
#include 
#include 
#include 

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

int p[maxn],v[maxn],cnt;
int num1[20],num2[20],cnt1[20],cnt2[20];
int Power[20];
int a,b,c,d,x,y;
int id;

void getprime() {
    for(int i = 2;i < maxn;i++) {
        if(v[i] == 0) {
            p[++cnt] = i;
            v[i] = i;
        }
        for(int j = 1;j <= cnt && 1ll * i * p[j] < maxn;j++) {
            v[i * p[j]] = p[j];
            if(i % p[j] == 0) break;
        }
    }
}

ll gcd(ll n,ll m) {
    return m == 0 ? n : gcd(m,n % m);
}

void init() {
    getprime();
    scanf("%d%d%d%d%d%d",&a,&b,&c,&d,&x,&y);
    ll num = gcd(x,y);
    for(int i = 1;i <= cnt;i++) {
        int amt1 = 0,amt2 = 0;
        while(x % p[i] == 0) {
            x /= p[i];
            amt1++;
        }
        while(y % p[i] == 0) {
            y /= p[i];
            amt2++;
        }
        if(num % p[i] == 0) {
            num1[++id] = p[i];
            cnt1[id] = amt1;
            
            num2[id] = p[i];
            cnt2[id] = amt2;
        }
        if(x == 1 || y == 1) break;
    }
    
    if(num % x == 0 && x != 1) {
        num1[++id] = x;
        cnt1[id] = 1;
        
        num2[id] = x;
        cnt2[id] = 1;
    }
    for(int i = 1;i <= id;i++) Power[i] = 0;
}

int qpow(int x,int n) {
    int res = 1;
    while(n) {
        if(n & 1) res = 1ll * res * x % mod;
        x = 1ll * x * x % mod;
        n >>= 1;
    }
    return res;
}

void solve() {
    ll ans = 1;
    for(int i = a;i <= b;i++) {
        for(int j = 1;j <= id;j++) {
            ll amt1 = 1ll * i * cnt1[j]; //x第j个素数的幂
            ll amt2 = (amt1 + cnt2[j] - 1) / cnt2[j]; //y至少要几次幂才能大于等于x对应的
            amt1 %= mod - 1;
            if(amt2 > d) {
                Power[j] = Power[j] + 1ll *  (c + d) * (d - c + 1) / 2 % (mod - 1) * cnt2[j] % (mod - 1);
                Power[j] %= mod - 1;
            } else if(amt2 <= c) {
                Power[j] = Power[j] + amt1 % (mod - 1) * (d - c + 1) % (mod -
                                                                        1);
                Power[j] %= mod - 1;
            } else {
                Power[j] = Power[j] + i % (mod - 1) * cnt1[j] % (mod - 1) * (d - amt2 + 1) % (mod - 1);
                Power[j] %= mod - 1;
                Power[j] = Power[j] + (amt2 - 1 + c) * (amt2 - c) / 2 % (mod - 1) * cnt2[j] % (mod - 1);
                Power[j] %= mod - 1;
            }
        }
    }
    for(int i = 1;i <= id;i++) {
        ans = ans * qpow(num1[i],Power[i]) % mod;
    }
    printf("%lld\n",ans);
}

int main() {
    init();
    solve();
    return 0;
}


你可能感兴趣的:(#,其他比赛题目,#,素数)