[关闭]
@wsndy-xx 2018-06-14T10:23:15.000000Z 字数 1056 阅读 971

Bzoj 2440 完全平方数

题解


question

求第 个无平方因子数,分解之后所有质因数的次数都为1的数

slove

二分答案,问题转化为 中无平方因子数个数
判断:对于 以内的所有质数, 以内的无平方因子数为
=0个质数乘积的平方的倍数的数的数量(1的倍数)
-每个质数的平方的倍数的数的数量(9的倍数,25的倍数, )
+每2个质数乘积的平方的倍数的数的数量(36的倍数,100的倍数, )
-
发现每个数字 前的符号为
then,check时只需判断 的大小即可
当然要首先筛出

与反演无关,是莫比乌斯函数的一个应用

Code

二分有个什么wobuzhidao的错误
发现比样例少 , 竟然过了,woc,why

  1. #include <bits/stdc++.h>
  2. #define LL long long
  3. const int N = 1e5 + 10;
  4. LL T, n, miu[N], prime[N], bo[N];
  5. void Make_miu() {
  6. miu[1] = 1;
  7. for(int i = 2; i < N; i ++) {
  8. if(!bo[i]) {prime[++ prime[0]] = i; miu[i] = -1;} // 1个质因子
  9. for(int j = 1; j <= prime[0] && prime[j] * i < N; j ++) {
  10. bo[i * prime[j]] = 1; // 非素数
  11. if(i % prime[j] == 0) {
  12. miu[i * prime[j]] = 0; // 有 prime[j] * prime[j]
  13. break;
  14. } else { // 与 i 质因子的个数奇偶性相反
  15. miu[i * prime[j]] = - miu[i];
  16. }
  17. }
  18. }
  19. }
  20. bool See(LL x, LL t) {
  21. LL ret(0);
  22. for(LL i = 1; i * i <= x; i ++) ret += (miu[i] * (x / (i * i)));
  23. return ret < t;
  24. }
  25. LL Get_Ans(LL x) {
  26. LL L = 0, R = x * 2, Ans;
  27. while(L <= R) {
  28. LL Mid = (L + R) >> 1;
  29. if(See(Mid, x)) L = Mid + 1, Ans = Mid;
  30. else R = Mid - 1;
  31. }
  32. return Ans;
  33. }
  34. int main() {
  35. std:: cin >> T;
  36. Make_miu();
  37. for(; T --; ) {
  38. std:: cin >> n;
  39. std:: cout << Get_Ans(n) + 1 << "\n";
  40. }
  41. return 0;
  42. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注