传送门
题目大意:
首先看到 g c d gcd gcd就应该想到 g c d gcd gcd的本质,即质因数分解后对于相同的质因子取 m i n ( p 1 , p 2 ) min(p_1,p_2) min(p1,p2),而且不难发现对 x , y x,y x,y求幂,不会影响质因子的种类,只是会改变指数,而且是以等差数列增长的。显然只需要一次质因数分解记录底数和对应指数,使用map记录相同的质因子以及各自初始对应的个数,然后考虑指数的变化
显然我们只需要遍历 a a a或者 b b b的相同质因子从 a − b a-b a−b(或者 c − d c-d c−d)的数目作为初始值,然后考虑另一个数在区间对应指数是一个等差数列,只要除以它算出一个商,然后考虑这个商和区间 [ c , d ] [c,d] [c,d]的关系即可,具体细节画图更容易找到
需要注意的是指数会爆long long,使用__int128处理指数即可
#include <bits/stdc++.h>
#include <unordered_map>
#include <unordered_set>
using namespace std;
#define fi first
#define se second
#define pb push_back
#define ins insert
#define Vector Point
#define lowbit(x) (x&(-x))
#define mkp(x,y) make_pair(x,y)
#define mem(a,x) memset(a,x,sizeof a);
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<double,double> pdd;
const double eps=1e-8;
const double pi=acos(-1.0);
const int inf=0x3f3f3f3f;
const double dinf=1e300;
const ll INF=1e18;
const int Mod=998244353;
const int maxn=2e5+10;
ll gcd(ll a,ll b){
return b==0?a:gcd(b,a%b);
}
void getPrime(int *fac,int *num,int n,int &cnt){
int m=sqrt(n+0.5);
cnt=0;
for(int i=2;i<=m;i++){
if(n%i==0){
fac[cnt]=i;
while(n%i==0){
num[cnt]++;
n/=i;
}
cnt++;
}
if(n==1) break;
}
if(n>1){
fac[cnt]=n;
num[cnt++]++;
}
}
ll qkp(ll x,__int128 n,ll p){
ll ans=1;
while(n){
if(n&1) ans=ans*x%p;
x=x*x%p;
n>>=1;
}
return ans;
}
int facx[maxn],facy[maxn];
int num1[maxn],num2[maxn];
int cnt1,cnt2;
vector<int> cfac;
vector<int> numx,numy;
unordered_map<int,int> mp;
int main(){
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int a,b,c,d,x,y;
cin>>a>>b>>c>>d>>x>>y;
getPrime(facx,num1,x,cnt1);
getPrime(facy,num2,y,cnt2);
for(int i=0;i<cnt1;i++) mp[facx[i]]=1;
for(int i=0;i<cnt2;i++) if(mp.count(facy[i])){
cfac.push_back(facy[i]),mp[facy[i]]++;
numy.push_back(num2[i]);
}
for(int i=0;i<cnt1;i++){
if(mp[facx[i]]>1){
numx.push_back(num1[i]);
}
}
ll ans=1;
for(int i=0;i<cfac.size();i++){
__int128 sum=0;
for(int j=a;j<=b;j++){
int p=j*numx[i]/numy[i],q=j*numx[i]%numy[i];
if(p<c){
sum+=(__int128)j*numx[i]*(d-c+1);
}else if(p>=d){
sum+=(__int128)numy[i]*(c+d)*(d-c+1)/2;
}else{
sum+=(__int128)numy[i]*(c+p)*(p-c+1)/2;
sum+=(__int128)j*numx[i]*(d-p);
}
}
ans=ans%Mod*qkp(cfac[i],sum,Mod)%Mod;
}
cout<<ans<<"\n";
return 0;
}