【GDOI2018模拟8.11】质数
2017-08-11 19:04
344 查看
Description:
1<=n<=10^12
题解:
看到这种题就会想这是不是反演题。如果它是一道反演题,那它必须要有gcd来,题目中没有gcd,所以能不能变换出gcd呢。
实际上2f(x)=[gcd(i,j)=1]∗[i∗j=x],即考虑每一个p^q是给i还是给j。
Ans=∑ni=1∑j|i[gcd(j,ij)=1]
=∑ni=1∑⌊ni⌋j=1[gcd(i,j)=1]
=∑ni=1∑⌊ni⌋j=1∑d|gcd(i,j)μ(d)
=∑ni=1∑d|iμ(d)∗⌊nid⌋
=∑nd=1μ(d)∗∑⌊nd⌋i=1⌊nid2⌋
观察式子,减去不必要的循环,缩小循环范围。
=∑n√d=1μ(d)∗∑⌊nd2⌋i=1⌊nid2⌋
线筛出μ,外层暴力枚举d,μ(d) ≠ 0时再内层循环分块。
∑ni=1[μ(i)≠0]
=∑(√n)i=1μ(i)∗⌊ni2⌋
根据打表可得:
≈0.607n(n>=106)
时间复杂度证明:
T=∑n√i=1ni2−−√
=∑n√i=1n√i
≈n√ logn√2
那么就是O(0.607n√ logn√2)
Code:
#include<cstdio> #define ll long long #define fo(i, x, y) for(ll i = x; i <= y; i ++) using namespace std; const ll N = 1000000, mo = 998244353; ll mu[N + 5], p , n, ans, s; bool bz[N + 5]; int main() { mu[1] = 1; fo(i, 2, N) { if(!bz[i]) p[++ p[0]] = i, mu[i] = -1; fo(j, 1, p[0]) { ll k = i * p[j]; if(k > N) break; bz[k] = 1; if(i % p[j] == 0) { mu[k] = 0; break; } mu[k] = -mu[i]; } } scanf("%lld", &n); for(ll d = 1; d * d <= n; d ++) if(mu[d] != 0){ ll m = n / (d * d); s = 0; fo(i, 1, m) { ll j = m / (m / i); s += (ll)(m / i) * (j - i + 1) % mo; i = j; } ans += s * mu[d]; } printf("%lld", (ans % mo + mo) % mo); }
相关文章推荐
- 【JZOJ5250】【GDOI2018模拟8.11】质数
- 【GDOI2018模拟8.11】质数
- [JZOJ5250]【GDOI2018模拟8.11】质数
- 【jzoj5250】【GDOI2018模拟8.11】【质数】
- 【JZOJ 5250】【GDOI2018模拟8.11】质数
- 【JZOJ5250】【GDOI2018模拟】质数(数论)
- 质数,函数【GDOI2018模拟7.8】
- 【jzoj5251】【GDOI2018模拟8.11】【决战】【状态压缩动态规划】
- 【GDOI2018模拟7.8】质数 乱搞+哥德巴赫猜想
- 【GDOI2018模拟8.11】决战
- 【GDOI2018模拟7.8】质数
- GDOI’2018前模拟和刷题记录(长期更新)
- 【GDOI2018模拟9.14】通信
- 【JZOJ5219】【GDOI2018模拟7.10】B
- 【JZOJ 5220】【GDOI2018模拟7.10】C
- 【JZOJ5220】【GDOI2018模拟7.10】C
- 【jzoj5220】【GDOI2018模拟7.10】【C】【动态规划】
- 【jzoj5222】【GDOI2018模拟7.12】【A】【数据结构】
- 【jzoj5238】【GDOI2018模拟8.7】【的士碰撞】
- [JZOJ5261]【GDOI2018模拟8.12】求和