2020牛客多校第九场E

29 篇文章 0 订阅
26 篇文章 0 订阅

求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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值