P2257 YY的GCD
题意描述:
求 ,
solution:
反演进阶题。
先枚举一下 可得:
由
可得:
先枚举一下 可得:
化 可得:
然后我们就可以直接把 ,给求出来。
考虑枚举每个质因数 ,那么 只会对他的倍数有贡献。这样的复杂度就降为 的了。
剩下的部分整除分块即可。
总的时间复杂度为 (大力吸氧就过了)
Code
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#define int long long
const int N = 1e7+10;
int T,n,m,tot;
int prime[N],mu[N],ans[N];
bool check[N];
inline int read()
{
int s = 0,w = 1; char ch = getchar();
while(ch < '0' || ch > '9'){if(ch == '-') w = -1; ch = getchar();}
while(ch >= '0' && ch <= '9'){s = s * 10 + ch - '0'; ch = getchar();}
return s * w;
}
void YYCH()
{
mu[1] = 1;
for(int i = 2; i <= N-5; i++)
{
if(!check[i])
{
prime[++tot] = i;
mu[i] = -1;
}
for(int j = 1; j <= tot && i * prime[j] <= N-5; j++)
{
check[i * prime[j]] = 1;
if(i % prime[j] == 0)
{
mu[i * prime[j]] = 0;
break;
}
else mu[i * prime[j]] = -mu[i];
}
}
for(int i = 1; i <= tot; i++)
{
for(int j = 1; j * prime[i] <= N-5; j++)
{
ans[j * prime[i]] += mu[j];
}
}
for(int i = 1; i <= N-5; i++) ans[i] = ans[i-1] + ans[i];
}
int calc(int n,int m)
{
int res = 0;
if(n > m) swap(n,m);
for(int l = 1, r; l <= n && l <= m; l = r+1)
{
r = min(n/(n/l),m/(m/l));
res += (ans[r] - ans[l-1]) * (n/l) * (m/l);
}
return res;
}
signed main()
{
T = read(); YYCH();
while(T--)
{
n = read(); m = read();
printf("%lld\n",calc(n,m));
}
return 0;
}
其实这道题还可以做到 的。
最后一步 化 的时候,可以变为:
后面那个 是可以线性筛的。
设 , 只有当 时, 才成立。
1.当 为质数的时候,显然
2.当 时,显然
3.当 % 的时候:
证明:
此时 为 的最小质因子 。
显然 分解质因数后, 的次数是大于等于 的,所以除了 之外,其他都为零。
因为 的次数大于等于 2, 。
所以 .
4.当 % 时:
证明:
此时 为 的最小质因子 。
显然有 。假设 ,他分解后质因数为
比 多了个质因子 , 所以 。
综上:
然后就可以直接线性筛了。
Code
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#define int long long
const int N = 1e7+10;
int T,n,m,tot;
int prime[N],mu[N],ans[N];
bool check[N];
inline int read()
{
int s = 0,w = 1; char ch = getchar();
while(ch < '0' || ch > '9'){if(ch == '-') w = -1; ch = getchar();}
while(ch >= '0' && ch <= '9'){s = s * 10 + ch - '0'; ch = getchar();}
return s * w;
}
void YYCH()
{
mu[1] = 1; ans[1] = 0;
for(int i = 2; i <= N-5; i++)
{
if(!check[i])
{
prime[++tot] = i;
mu[i] = -1;
ans[i] = 1;
}
for(int j = 1; j <= tot && i * prime[j] <= N-5; j++)
{
check[i * prime[j]] = 1;
if(i % prime[j] == 0)
{
mu[i * prime[j]] = 0;
ans[i * prime[j]] = mu[i];
break;
}
else
{
mu[i * prime[j]] = -mu[i];
ans[i * prime[j]] = mu[i] - ans[i];
}
}
}
for(int i = 1; i <= N-5; i++) ans[i] = ans[i-1] + ans[i];
}
int calc(int n,int m)
{
int res = 0;
if(n > m) swap(n,m);
for(int l = 1, r; l <= n && l <= m; l = r+1)
{
r = min(n/(n/l),m/(m/l));
res += (ans[r] - ans[l-1]) * (n/l) * (m/l);
}
return res;
}
signed main()
{
T = read(); YYCH();
while(T--)
{
n = read(); m = read();
printf("%lld\n",calc(n,m));
}
return 0;
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux glibc自带哈希表的用例及性能测试
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 现代计算机视觉入门之:什么是图片特征编码
· 手把手教你在本地部署DeepSeek R1,搭建web-ui ,建议收藏!
· Spring AI + Ollama 实现 deepseek-r1 的API服务和调用
· 数据库服务器 SQL Server 版本升级公告
· 程序员常用高效实用工具推荐,办公效率提升利器!
· C#/.NET/.NET Core技术前沿周刊 | 第 23 期(2025年1.20-1.26)