[luogu5176] 公约数
题目描述
求
\]
由于答案可能过大,输出答案对10^9+7109+7取模的值。
输入输出
第一行一个正整数T,为数据组数。
下面T行,每行3个整数,为n,m,p。
输出格式
共T行,每行一个整数,为答案。
输入输出
2
10 12 11
30 20 25
输出样例
25302
573830
Solution
挺巧妙的一个题。
注意到\(\gcd\)的一个性质,我们只考虑一个质因子,设\(i=p^x,j=p^y,k=p^z\),可以得到:
\]
那么根据这个我们可以尝试着化简题目给出的式子,通分之后把分母提出来,和前面两项乘起来就是:
\]
由于这里只考虑一个质因子,我们可以两边取\(\log\),然后设\(\min(x,y,z)=x\),即\(x\)为最小值,这对答案是没有影响的,那么式子可以变成这样:
\]
可以发现\(y+z-x\geqslant y,y+z-x\geqslant z\),所以可以得到:
\]
所以:
\]
所以我们可以惊奇的发现,前面两项和分母约掉了,剩下的式子写出来就是:
\]
这个直接大力反演就好了。
#include<bits/stdc++.h>
using namespace std;
void read(int &x) {
    x=0;int f=1;char ch=getchar();
    for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f;
    for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=f;
}
void print(int x) {
    if(x<0) putchar('-'),x=-x;
    if(!x) return ;print(x/10),putchar(x%10+48);
}
void write(int x) {if(!x) putchar('0');else print(x);putchar('\n');}
const int maxn = 2e7+10;
const int mod = 1e9+7;
int pri[maxn/10],mu[maxn],f[maxn],vis[maxn],tot;
void sieve() {
	mu[1]=f[1]=1;
	for(int i=2;i<maxn;i++) {
		if(!vis[i]) pri[++tot]=i,mu[i]=-1,f[i]=1ll*i*i%mod-1;
		for(int v,j=1;j<=tot&&i*pri[j]<maxn;j++) {
			vis[v=i*pri[j]]=1;
			if(i%pri[j]==0) {f[v]=1ll*f[i]*pri[j]%mod*pri[j]%mod;break;}
			f[v]=1ll*f[i]*f[pri[j]]%mod,mu[v]=-mu[i];
		}
	}
	for(int i=1;i<maxn;i++) f[i]=(f[i]+f[i-1])%mod;
}
int calc(int n,int m) {
	int T=1,res=0;
	while(T<=min(n,m)) {
		int pre=T;T=min(n/(n/T),m/(m/T));
		res=(res+1ll*(f[T]-f[pre-1])*(n/T)%mod*(m/T)%mod)%mod;T++;
	}return (res+mod)%mod;
}
int main() {
	sieve();
	int T,n,m,p;read(T);
	while(T--) read(n),read(m),read(p),write(((1ll*calc(n,m)*p%mod+1ll*calc(n,p)*m%mod)%mod+1ll*calc(m,p)*n%mod)%mod);
	return 0;
}
												
											[luogu5176] 公约数的更多相关文章
- Luogu5176 公约数 莫比乌斯反演、线性筛
		
传送门 好像是我们联考时候的题目? 一个结论:\(\gcd(ij,ik,jk) \times \gcd(i,j,k) = \gcd(i,j) \times \gcd(i,k) \times \gcd( ...
 - xgzc— math 专题训练(一)
		
Lucas定理 当\(p\)是质数时,有\((^n_m)\equiv(^{n/p}_{m/p}) * (^{n\%p}_{m\%p}) \pmod{p}\) 狄利克雷卷积 定义:\((f*g)(n)= ...
 - C语言辗转相除法求2个数的最小公约数
		
辗转相除法最大的用途就是用来求两个数的最大公约数. 用(a,b)来表示a和b的最大公约数. 有定理: 已知a,b,c为正整数,若a除以b余c,则(a,b)=(b,c). (证明过程请参考其它资料) 例 ...
 - 求两个数字的最大公约数-Python实现,三种方法效率比较,包含质数打印质数的方法
		
今天面试,遇到面试官询求最大公约数.小学就学过的奥数题,居然忘了!只好回答分解质因数再求解! 回来果断复习下,常用方法辗转相除法和更相减损法,小学奥数都学过,很简单,就不细说了,忘了的话可以百度:ht ...
 - BZOJ4488: [Jsoi2015]最大公约数
		
Description 给定一个长度为 N 的正整数序列Ai对于其任意一个连续的子序列{Al,Al+1...Ar},我们定义其权值W(L,R )为其长度与序列中所有元素的最大公约数的乘积,即W(L,R ...
 - 求N个数的最大公约数和最小公倍数(转)
		
除了分解质因数,还有另一种适用于求几个较小数的最大公约数.最小公倍数的方法 下面是数学证明及算法实现 令[a1,a2,..,an] 表示a1,a2,..,an的最小公倍数,(a1,a2,..,an)表 ...
 - 辗转相除法求最大公约数,非goto
		
#include<iostream> using namespace std; //不推荐用goto,当然用它更快 //辗转相除法求两数的最大公约数 int gcd(long int a, ...
 - ZOJ Problem Set - 1337 Pi 最大公约数
		
这道题目的关键在于怎么求两个整数的最大公约数,这里正好复习一下以前的知识,如下: 1.设整数a和b 2.如果a和b都为0,则二者的最大公约数不存在 3.如果a或b等于0,则二者的最大公约数为非0的一个 ...
 - Euclid求最大公约数
		
Euclid求最大公约数算法 #include <stdio.h> int gcd(int x,int y){ while(x!=y){ if(x>y) x=x-y; else y= ...
 
随机推荐
- C#防止程序重新运行
			
//禁止重复运行 bool ret; Mutex mutex = new Mutex(true, Application.ProductName, out ret); if (ret) { Appli ...
 - Eclipse - 配置优化
			
去除不需要的启动加载项 Window --> Preferences -->General --> Startup and Shutdown 关闭自动更新 Window --> ...
 - L010小结后自考题
			
. 查询2号分区的inode和block的数量和尺寸 . 在lcr文件夹下创建一个a文件夹,然后进入文件夹中,创建3个3层目录,5个1层目录,5个文件 . 滤出a文件夹下的所有一级目录(4种方法) . ...
 - OSG-交互
			
本文转至http://www.cnblogs.com/shapherd/archive/2010/08/10/osg.html 作者写的比较好,再次收藏,希望更多的人可以看到这个文章 互联网是是一个相 ...
 - selenium,unittest——参数化url,并多线程加快脚本运行速度
			
利用参数化连续打开网页: #encoding=utf-8import unittestimport paramunittestimport timefrom selenium import webdr ...
 - Linux命令应用大词典-第2章 获取帮助
			
2.1 help:查看内部Shell命令帮助信息 2.2 man:显示在线手册页 2.3 manpath:查看和设置man手册页的查询路径 2.4 info:阅读info格式的文件 2.5 pinfo ...
 - Unity编辑器 - 自动排版
			
Unity编辑器 - 自动排版 使用花括号提高可读性 //一组横向排列的控件 GUILayout.BeginHorizontal(); { GUILayout.BeginVertical(); { / ...
 - Oracle存储过程练习题
			
1.1.创建一个过程,能向dept表中添加一个新记录.(in参数) 创建过程 create or replace procedure insert_dept ( num_dept in number, ...
 - AVL树和伸展树 -数据结构(C语言实现)
			
读数据结构与算法分析 AVL树 带有平衡条件的二叉树,通常要求每颗树的左右子树深度差<=1 可以将破坏平衡的插入操作分为四种,最后通过旋转恢复平衡 破坏平衡的插入方式 描述 恢复平衡旋转方式 L ...
 - 【Linux 运维】查看网络连接状态信息之netstat和ss命令详解
			
一.netstat 常用命令详解 通过man netstat可以查看netstat的帮助信息: netstat 命令:用于显示各种网络相关信息,如网络连接,路由表,接口状态,无效连接,组播成员 等等. ...