[关闭]
@11101001 2018-08-23T19:18:44.000000Z 字数 1699 阅读 781

bzoj4407: 于神之怒加强版

莫比乌斯反演


题目链接

bzoj4407: 于神之怒加强版

题解

求这个东西


然后是套路

显然,它是个积性函数
尝试线筛

考虑一个只有一个质因数的情况
所以
对于不同质因数,因为是积性函数,直接乘起来

代码

  1. #include<cstdio>
  2. #include<algorithm>
  3. inline int read() {
  4. int x = 0,f = 1 ;
  5. char c = getchar();
  6. while(c < '0' || c > '9')c = getchar();
  7. while(c <= '9' && c >= '0') x = x * 10 + c - '0',c = getchar();
  8. return x * f;
  9. }
  10. const int mod = 1e9 + 7;
  11. int t,k;
  12. const int maxn = 5000007;
  13. int num,p[maxn],mu[maxn],F[maxn],tmp[maxn];
  14. bool np[maxn];
  15. int fstpow(int x,int k) {
  16. int ret = 1;
  17. for(;k;k >>= 1,x = 1ll * x * x % mod)
  18. if(k & 1) ret = 1ll * ret * x % mod;
  19. return ret;
  20. }
  21. const int M = 5000000;
  22. void pre(int k) {
  23. F[1] = mu[1] = 1;
  24. for(int i = 2;i <= M;++ i) {
  25. if(!np[i]) p[++ num] = i, mu[i] = -1, tmp[num] = fstpow(i,k),F[i] = (tmp[num] - 1) % mod;
  26. for(int t,j = 1;j <= num && i * p[j] <= M;++ j) {
  27. t = i * p[j];
  28. np[t] = 1;
  29. if(i % p[j]) mu[t] = -mu[i],F[t] = 1ll * F[i] * F[p[j]] % mod;
  30. else {mu[t] = 0,F[t] = 1ll * F[i] * tmp[j] % mod; }
  31. }
  32. }
  33. for(int i = 2;i <= M;++ i) F[i] += F[i - 1],F[i] >= mod && (F[i] -= mod);
  34. }
  35. long long solve(int n,int m) {
  36. long long ret = 0;
  37. for(int i = 1,nxt;i <= std::min(n,m);i = nxt + 1) {
  38. nxt = std::min(n / (n / i),m / (m / i));
  39. ret += 1ll * (F[nxt] - F[i - 1] + mod) % mod * (n / i) % mod * (m / i) % mod;
  40. }
  41. return ret;
  42. }
  43. int main() {
  44. t = read(),k = read();
  45. pre(k);
  46. for(int n,m,i = 1;i <= t;++ i) {
  47. n = read(),m = read();
  48. printf("%lld\n",(solve(n,m) % mod + mod) % mod);
  49. }
  50. return 0;
  51. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注