首先化简成下面这样。 对于每个素数P都有一个1 N/P的区间让 a/p 和 b/p,我们只要算出区间内互质数的数对,枚举每个素数求和就是答案。 由欧拉函数可以求得1 到 N 中与N互质的数的个数 对其求前缀和 ,就是数对的一半了,这里a b 是可以交换的 。(当 a b 相等 为 p 的时候 就不能了)
参考文章
#include #include #include #include #include #include #include #include using namespace std; const int INF = 0x3f3f3f3f; const int N = 1e7 + 10 ; bool st [ N ] ; int prm[ N ] ; int hi[ N ] ; long long sum[ N ] ; int cnt = 1 ; void in (int n ) { cnt = 1 ; st[1] = 1 ; hi[1] = 1 ; for (int i = 2 ; i <= n ; i++ ) { if ( ! st[i] ) { prm[cnt] = i ; cnt++ ; hi[i] = i - 1 ; } for (int j = 1 ; i*prm[j] <= n ; j++ ) { st[i*prm[j]] = 1 ; if ( i % prm[j] == 0 ) { hi[i*prm[j]] = hi[i] * prm[j] ; break; } hi[ i*prm[j] ] = hi[i] * ( prm[j] - 1 ) ; } } } int main () { ios::sync_with_stdio(false); int n ; cin >> n ; in(n); long long re = 0 ; for (int i = 1 ; i <= n ; i++ ) { sum[i] = sum[ i-1 ] + hi[i] ; } for (int i = 1 ; i < cnt ; i++ ) { int p = prm[i] ; re += 2*sum[ n / p ] - 1 ; } cout << re << "n" ; return 0 ; }
上一篇 leetcode 576. Out of Boundary Paths | 576. 出界的路径数(暴力递归->傻缓存->dp)
下一篇 2021-10-05
版权所有 (c)2021-2022 MSHXW.COM
ICP备案号:晋ICP备2021003244-6号