hdu 6706
Posted 19992147orz
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu 6706相关的知识,希望对你有一定的参考价值。
杜教筛+欧拉函数
答案等价于
$\sum_i=1^n\sum_j=1^i(i-j)[gcd(i,j)==1]$
欧拉函数$\phi(i)$表示比$i$小且与$i$互质的数的个数
那么进一步化简,答案等于
$\frac\sum_i=1^n\phi(i)*i2-1$
$\phii*i$是一个积性函数,可以杜教筛
设$f(i)=\phi(i)*i$,$g(i)=i$
那么
$f*g=\sum_n|df(d)*\fracnd$
$=\sum_n|d\phi(d)*d*\fracnd$
$=\sum_n|d\phi(d)*n$
$=n\sum_n|d\phi(d)$
因为$\sum_n|d\phi(d)=n$
所以$f*g=n^2$
那么就可以杜教筛了

#include <bits/stdc++.h> using namespace std; const int maxn = 1e6 + 5, P = 1e9 + 7, inv2 = 500000004, inv6 = 166666668; int n, a, b; int phi[maxn], p[maxn], mark[maxn]; map<int, int> mp; void init() phi[1] = 1; for(int i = 2; i < maxn; ++i) if(!mark[i]) p[++p[0]] = i; phi[i] = i - 1; for(int j = 1; j <= p[0] && i * p[j] < maxn; ++j) mark[i * p[j]] = 1; if(i % p[j] == 0) phi[i * p[j]] = phi[i] * p[j]; break; phi[i * p[j]] = phi[i] * phi[p[j]]; for(int i = 1; i < maxn; ++i) phi[i] = (1LL * phi[i] * i % P + phi[i - 1]) % P; int cal(int x) return 1LL * x * (x + 1) % P * inv2 % P; int dj(int n) if(n < maxn) return phi[n]; if(mp.find(n) != mp.end()) return mp[n]; int ret = 1LL * n * (n + 1) % P * (2LL * n + 1) % P * inv6 % P; for(int i = 2, j; i <= n; i = j + 1) j = n / (n / i); ret = (ret - 1LL * (cal(j) - cal(i - 1) + P) % P * dj(n / i) % P + P) % P; return mp[n] = ret; int main() init(); int T; scanf("%d", &T); while(T--) scanf("%d%d%d", &n, &a, &b); printf("%d\n", 1LL * (dj(n) - 1) * inv2 % P); return 0;
以上是关于hdu 6706的主要内容,如果未能解决你的问题,请参考以下文章
HDU6706 CCPC 2019网络赛 huntian oy 推式子+杜教筛