求gcd(x,y) 无非就是求x和y的所有质因子表示中,取相同质因子且次数最小的,
例如 gcd(2,3) -> 21 31 -> 1(没有相同的) gcd(2,8) 21 23 -> 2 gcd(2,12) -> 21 22 X 31 -> 2
先想暴力做法,先把x,y用唯一分解定律分解出来,之后对于每一个相同的质因子,两个循环,判断哪个的次数小就取哪个。
这样无非就是超时。
cx 为 x的一个质数的次数,cy同理
所以,我们可以直接将两个循环拆开,对于i*cx,求一下它对应需要多少倍(cnt)的cy才能比它大,之后比它大的都选这个小的。同理另外一个循环也是。
更多细节代码上有注释。
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#include<bits/stdc++.h>
#define int long long
#define sc scanf
#define pf printf
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
typedef unsigned long long LL;
const int INF = 0x3f3f3f3f;
const double eps = 1e-4;
const int mod = 998244353;
const int N = 200010;
int a,b,c,d,x,y;
int qmi(int a,int b){
int res = 1;
while(b){
if(b & 1) res = res*a % mod;
a = (a*a)%mod;
b >>= 1;
}
return res;
}
map<int,int> mp[2];
void fenjie(int id,int n){
for(int i=2;i<=n/i;i++){
if(n%i == 0){
int c = 0;
while(n%i == 0) c++,n/=i;
mp[id][i] = c;
}
}
if(n > 1) mp[id][n] = 1;
}
void slove(){
fenjie(0,x);//分解质因数
fenjie(1,y);
int res = 1;
for(auto i : mp[0]){//遍历质因数
int p = i.first,cx = i.second,cy = mp[1][p];
if(cy == 0) continue;//质因数不相同,不处理
int tol = 0;
for(int i=a;i<=b;i++){//第一个循环
int cnt = max(c-1ll,i*cx/cy);//计算出i*cx需要需要c~d中的哪个数乘cy才能比它大
(tol += max(0ll,d-cnt)*i*cx) %= mod-1;//有可能会是i*cx始终最大
//次数取余 mod-1
}
for(int i=c;i<=d;i++){
//为什么这里要减1,不应该和上面一样?
//因为当次数一样的时候,对于上一个循环,我们是默认了不选它作为最大值,所
//以这里要选,而对于其他的数减1之后没有影响。
int cnt = max(a-1ll,(i*cy-1)/cx);
(tol += max(0ll,b-cnt)*i*cy) %= mod-1;
}
res = (res*qmi(p,tol)) % mod;
}
cout<<res<<endl;
}
signed main(){
IOS;
#ifdef ddgo
freopen("C:/Users/asus/Desktop/ddgoin.txt","r",stdin);
#endif
cin>>a>>b>>c>>d>>x>>y;
slove();
return 0;
}