唯一分解 [2020牛客暑期多校训练营(第九场) Groundhog Chasing Death]

唯一分解 2020牛客暑期多校训练营(第九场) Groundhog Chasing Death

题解:

因为是求gcd,所以先对 x ,y 进行唯一分解,求出共有的素因子和个数。

然后枚举每一个素因子,枚举x的数量,求出y。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+10;
const int mod = 998244353;
typedef long long ll;
int pri[maxn],cnt,v[maxn];
void init() {
    cnt = 0;
    memset(v,0,sizeof(v));
    for (int i = 2; i < maxn; ++i) {
        if (!v[i]) v[i] = i,pri[cnt++] = i;
        for (int j = 0; j < cnt; ++j) {
            if (1ll * i * pri[j] >= maxn) break;
            v[i * pri[j]] = pri[j];
        }
    }
}
ll a,b,c,d,x,y;
ll cntx[maxn],cnty[maxn],isp[maxn],tot;
void judge(){
	tot = 0;
	for(int i = 0; i < cnt; i++){
		if(x % pri[i] == 0 && y % pri[i] == 0){
			isp[++tot] = pri[i];
			while(x % pri[i] == 0) cntx[tot]++,x/=pri[i];
			while(y % pri[i] == 0) cnty[tot]++,y/=pri[i];
		}
		while(x % pri[i] == 0) x /= pri[i];
		while(y % pri[i] == 0) y /= pri[i];
	}
	if(x != 1 && x == y){
		isp[++tot] = x;
		cntx[tot] = cnty[tot] = 1;
	}
}

long long binpow(long long x,long long k) {
    x %= mod;
    long long ans = 1;
    while (k) {
        if (k & 1) ans = ans * x % mod;
        x = x * x % mod;
        k >>= 1;
    }
    return ans;
}

int main(){
	scanf("%lld%lld%lld%lld%lld%lld",&a,&b,&c,&d,&x,&y);
	ll ans = 1;
	init(),judge();
	for(int i = 1; i <= tot; i++){
		ll res = 0;
		for(int j = a; j <= b; j++){
			ll num = cntx[i]*j;
			ll r = num/cnty[i];
			if(r <= d && r >= c ) {
				res += 1ll*(c + r)*(r - c + 1)/2*cnty[i];
				res += 1ll*(d - r)*cntx[i]*j;
			}
			else if(r > d) res += 1ll*(c + d)*(d - c + 1)/2*cnty[i];
			else if(r < c) res += 1ll*(d - c + 1)*cntx[i]*j;
			res %= mod-1;
			// printf("j=%d res=%lld r=%d
",j,res,r);
		}
		// printf("res=%lld isp[%d]=%d
",res,i,isp[i]);
		ans = ans*binpow(isp[i],res)%mod;
	}
	printf("%lld
",ans);
	return 0;
}


原文地址:https://www.cnblogs.com/EchoZQN/p/13460414.html