P8926 「GMOI R1-T3」Number Pair

题目描述

我们定义满足如下条件的数对 (x,y)(x,y)(x,y) 叫做奇妙数对:

k×gcd⁡(x,y)=lcm⁡(x,y)k \times \gcd(x,y)=\operatorname{lcm}(x,y)k×gcd(x,y)=lcm(x,y) 并且 P≤gcd⁡(x,y)≤QP \le \gcd(x,y) \le QPgcd(x,y)Q(保证 P≤QP \le QPQ)。

TTT 组数据,对于每一组数据,给定 k,P,Qk,P,Qk,P,Q 三个数,求符合条件的数对 (x,y)(x,y)(x,y) 的对数。

答案对 109+710^9+7109+7 取模。

输入格式

本题有多组数据。

第一行一个整数 TTT,表示数据数量。

接下来 TTT 行,每行三个整数 k,P,Qk,P,Qk,P,Q

输出格式

对于每一组数据,给出对应答案,每组数据一行。

输入输出样例 #1

输入 #1

5
10 1 3
30 1 5
997 24 35
34 39 99
210 1000 1001

输出 #1

12
40
24
244
32

说明/提示

注意并不寻常的时间限制。

对于 100%100\%100% 的数据 1≤k≤10161 \le k \le 10^{16}1k10161≤T≤501 \le T \le 501T501≤P≤Q≤2×1091 \le P \le Q \le 2\times 10^91PQ2×109

测试点 kkk TTT PPP QQQ 总分
1∼31\sim 313 k≤3k \le 3k3 T=1T=1T=1 P=1P=1P=1 Q=1Q=1Q=1 151515
4∼84\sim 848 k≤100k \le 100k100 T≤8T \le 8T8 P≤30P \le 30P30 Q≤30Q \le 30Q30 151515
9∼139\sim 13913 k≤103k \le 10^3k103 T≤50T \le 50T50 P≤500P \le 500P500 Q≤500Q \le 500Q500 252525
14∼1814\sim 181418 k≤1012k \le 10^{12}k1012 T≤50T \le 50T50 P≤104P \le 10^4P104 Q≤104Q \le 10^4Q104 151515
19∼2219\sim 221922 k≤1013k \le 10^{13}k1013 T≤50T \le 50T50 P≤106P \le 10^6P106 Q≤106Q \le 10^6Q106 121212
23∼2823\sim 282328 k≤1016k \le 10^{16}k1016 T≤50T \le 50T50 P≤2×109P \le 2\times10^9P2×109 Q≤2×109Q \le 2\times10^9Q2×109 181818

本题保证 kkk 随机生成,并不存在极限卡人数据,时限已经开到 std 两倍,请各位选手放心。

C++实现

#include<bits/stdc++.h>
using namespace std;
int const N=6e6+10;
int cnt,prime[N];
long long const mod=1e9+7;
bitset<100000001>vis;
inline long long qpow(long long a,long long b,long long t=1){
	for(;b;b>>=1,a=a*a%mod)if(b&1)t=t*a%mod;return t;
	}
inline void work(int n){
	for(int i=2;i<=n;++i){
		if (!vis[i]) prime[++cnt]=i;
		for (int j=1;j<=cnt && i*prime[j]<=n;++j){
			vis[i*prime[j]]=1;
			if (i%prime[j]==0) break;
		} 
	}
}
signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);
	int t;cin>>t;work(100000000);
	while (t--){
		long long ans=0,k,p,q;
		cin>>k>>p>>q;
		for (int i=1;i<=cnt && prime[i]*prime[i]<=k;++i){
			if (k%prime[i]==0) ++ans;
			while (k%prime[i]==0) k/=prime[i];
		}
		if (k!=1) ++ans;
		cout<<(q-p+1)*qpow(2,ans)%mod<<'\n';
	}
	return 0;
}

在这里插入图片描述

后续

接下来我会不断用C++来实现信奥比赛中的算法题、GESP考级编程题实现、白名单赛事考题实现,记录日常的编程生活、比赛心得,感兴趣的请关注,我后续将继续分享相关内容

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐