E_Groundhog Chasing Death(不錯的數論)

2020-08-09 10:28:38

題目鏈接:E_Groundhog Chasing Death

題目大意

這一道裸的數論題,題意就不省略了。

解題思路

我們可以對 xyx和y 進行質因子分解,經過化簡我們可以得到下面 下麪這個公式
pi=abj=cdmin(in,jm)p^{\sum_{i=a}^{b} \sum_{j=c}^{d} min(i*n,j*m)}
pxynmxy其中p爲x和y的公共質因子個數,n和m分別表示x和y中分別有幾個
其中對於統計指數的個數的時候可以根據 nin*i 的大小去處理 mm
很明顯只有存在相同質因子的時候需要統計下該質因子的指數就可以。
注意的是根據費馬小定理對指數取模的時候應該是 %mod1\ \%(mod-1)

程式碼

/*

*/
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll mx=2000100;
const ll mod=998244353;
map<int,ll>mp;
ll a,b,c,d,ans=1;
ll poow(ll A,ll B){
	ll res=1;
	while(B){
		if(B&1) res=res*A%mod;
		A=A%mod*A%mod;
		B>>=1;
	}
	return res%mod;
}
// x表示 x中p的個數 y表示y中p的個數 
void ji_suan(ll x,ll y,ll p){
	ll sum=0;
	ll cnt;
	for(ll i=a;i<=b;i++){
		ll tem=x*i;
// 確定多少個 y以內 都是 現在的 x*i 大,
// 到時候只用求 關於 y 的前 ty 項和就可以		
		ll ty=tem/y; 
		ll flag=0;
		cnt=0;
// 如果 ty 小於 c 說明求和的時候 一直都是 x*i 小 		
		if(ty<c) flag=1; 
		if(ty>=c){
		// 計算 ty 的前 n 項和
		// 爲了防止 ty 大於 d 的情況需要取兩者的最小值	
			ll bb=min(ty,d);	
			cnt=y*(c+bb)*(bb-c+1)/2%(mod-1);
		}
		// 記錄指數的個數 
		sum=(sum+cnt)%(mod-1);
		cnt=0;
		if(ty<=d){
	// 這裏爲了防止 ty 下於 c	所以去最大值	
			ty=max(ty,c);
			cnt=tem*(d-ty+flag)%(mod-1);
			sum=(sum+cnt)%(mod-1);	
		}
	}
	// 記錄答案 
	ans=ans*poow(p,sum)%mod; 
}
int main(){	
	ios::sync_with_stdio(0);
	ll x,y;
	cin>>a>>b>>c>>d>>x>>y;
	//先對 x 進行質因子分解並且記錄每個質因子的個數 
	for(ll i=2;i*i<=x;i++){
		while(x%i==0){
			mp[i]++;
			x/=i;
		}
	}
	if(x!=1) mp[x]++;
	
	int num;bool f;
	for(ll i=2;i*i<=y;i++){
		num=0;
		f=0;
		if(y%i==0) f=1;
		while(y%i==0){
			num++;
			y/=i;
		}
// 對 y 進行質因子分解,如果有相同的因子的話
// 就進行判斷。		
		if(mp[i]&&f){
			ji_suan(mp[i],num,i);
		}
	}
	if(y!=1&&mp[y]){
		ji_suan(mp[y],1,y);
	}
	cout<<ans<<"\n";
    return 0;
}