唯一分解 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;
}