好久没有更新啦,今天上午就这一题卡了半天,然而只是一些小问题影响时间
这题目没法再简述了,题目描述很清晰
给定整数N,求1<=x,y<=N且Gcd(x,y)为素数的
数对(x,y)有多少对.
我们来看一下性质: gcd(x,y) = z, 那么gcd(x/z,y/z) = 1,这个是显然的,那我们不妨假设y >= x 那么答案基本也是显然的了
剩下的就是求欧拉函数了,枚举z即可,用前缀和记录即可(不要树状数组,粗暴记录就行了)
说说今天蹦的地方吧:先是Size开小了,然后是数组类型小了(前缀和会爆int),接着全改成long long后会mle,浪费了接近半小时,这提醒我们一定要注意数组的类型啊
#include <algorithm> #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <cmath> using namespace std; typedef long long ll; const int Size = 1e7 + 7; int n; int prime[Size],phi[Size],factor_max[Size]; ll sum[Size]; ll ans; void Euler(void); int main(){ scanf("%d",&n); Euler(); for(int i = 1;i <= n; ++i) sum[i] = sum[i - 1] + phi[i]; for(int i = 1;i <= prime[0]; ++i) ans += sum[n / prime[i]] * 2 - 1; printf("%lld",ans); return 0; } void Euler(void){ phi[1] = 1; for (int i = 2;i <= n; ++i){ if (!factor_max[i]){ factor_max[i] = i; prime[++prime[0]] = i; phi[i] = i-1; } for (int j = 1;j <= prime[0]; ++j){ if (prime[j] * i > n) break; if (i % prime[j] != 0) phi[i * prime[j]] = phi[i] * (prime[j] - 1); else phi[i * prime[j]] = phi[i] * prime[j]; factor_max[i * prime[j]] = prime[j]; if (i % prime[j] == 0) break; } } }