易得 $\sum\limits_{g=1}^{n} g \sum\limits_{k=1}^{n} \mu(k) \lfloor\frac{n}{gk}\rfloor \lfloor\frac{n}{gk}\rfloor $

记 \(T=gk\) 枚举 \(T\) ,注意这里既然满足 \(T=gk\) 要保证两个乘起来确实是 \(T\) ,选择把 \(k\) 换成 $\frac{T}{g} $ .

$\sum\limits_{T=1}^{n} \lfloor\frac{n}{T}\rfloor \lfloor\frac{n}{T}\rfloor \sum\limits_{g|T} g\mu(\frac{T}{g}) $

$\sum\limits_{T=1}^{n} \lfloor\frac{n}{T}\rfloor \lfloor\frac{n}{T}\rfloor \varphi(T) $

猜了一下每次回答都是根号,可能可以,但是交上去T了。原来这个时限是200ms,太惊人了,这道题卡掉了所有其他的思路。

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. typedef long long ll;
  4. const int MAXN=1000000;
  5. int prime[MAXN+1];
  6. int &ptop=prime[0];
  7. ll Phi[MAXN+1];
  8. inline void sieve(){
  9. const int &n=MAXN;
  10. Phi[1]=1;
  11. for(int i=2;i<=n;i++){
  12. if(!Phi[i]){
  13. ptop++;
  14. prime[ptop]=i;
  15. Phi[i]=i-1;
  16. }
  17. for(int j=1;j<=ptop;j++){
  18. int &p=prime[j];
  19. if(i*p>n)
  20. break;
  21. if(i%p){
  22. Phi[i*p]=Phi[i]*Phi[p];
  23. }
  24. else{
  25. Phi[i*p]=Phi[i]*p;
  26. break;
  27. }
  28. }
  29. }
  30. for(int i=1;i<=n;i++){
  31. Phi[i]+=Phi[i-1];
  32. }
  33. }
  34. inline ll H(int n){
  35. ll res=0;
  36. for(int l=1,r;l<=n;l=r+1){
  37. int t=n/l;
  38. r=n/t;
  39. res+=1ll*t*t*(Phi[r]-Phi[l-1]);
  40. }
  41. return res;
  42. }
  43. inline ll G(int n){
  44. ll res=(H(n)-1ll*n*(n+1)/2)/2;
  45. return res;
  46. }
  47. int main() {
  48. #ifdef Yinku
  49. freopen("Yinku.in","r",stdin);
  50. #endif // Yinku
  51. sieve();
  52. int n;
  53. while(~scanf("%d",&n)){
  54. if(n==0)
  55. break;
  56. else{
  57. printf("%lld\n",G(n));
  58. }
  59. }
  60. }

问题在哪里?莫比乌斯反演不擅长进行多次回答,观察题目的数据可能想让我们用埃筛?

回到上面的式子。


其实因为是 \(n==m\) ,上面的反演很多余,枚举 \(g\) 的时候可以发现另一个公式,但是好像复杂度也是一样的,先留着,这个也是可以用杜教筛跑出大数据,应该比反演要快(因为这样大的Phi是比上面的少的)。

易得 $\sum\limits_{g=1}^{n} g \sum\limits_{i=1}^{\lfloor\frac{n}{g}\rfloor} 2\varphi(i) - 1 $

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. typedef long long ll;
  4. const int MAXN=1000000;
  5. int prime[MAXN+1];
  6. int &ptop=prime[0];
  7. ll Phi[MAXN+1];
  8. inline void sieve(){
  9. const int &n=MAXN;
  10. Phi[1]=1;
  11. for(int i=2;i<=n;i++){
  12. if(!Phi[i]){
  13. ptop++;
  14. prime[ptop]=i;
  15. Phi[i]=i-1;
  16. }
  17. for(int j=1;j<=ptop;j++){
  18. int &p=prime[j];
  19. if(i*p>n)
  20. break;
  21. if(i%p){
  22. Phi[i*p]=Phi[i]*Phi[p];
  23. }
  24. else{
  25. Phi[i*p]=Phi[i]*p;
  26. break;
  27. }
  28. }
  29. }
  30. for(int i=1;i<=n;i++){
  31. Phi[i]+=Phi[i-1];
  32. }
  33. }
  34. inline ll s1(ll l,ll r){
  35. return (l+r)*(r-l+1)/2;
  36. }
  37. inline ll H(int n){
  38. ll res=0;
  39. for(int l=1,r;l<=n;l=r+1){
  40. int t=n/l;
  41. r=n/t;
  42. res+=(2ll*Phi[t]-1)*s1(l,r);
  43. }
  44. return res;
  45. }
  46. inline ll G(int n){
  47. ll res=(H(n)-1ll*n*(n+1)/2)/2;
  48. return res;
  49. }
  50. int main() {
  51. #ifdef Yinku
  52. freopen("Yinku.in","r",stdin);
  53. #endif // Yinku
  54. sieve();
  55. int n;
  56. while(~scanf("%d",&n)){
  57. if(n==0)
  58. break;
  59. else{
  60. printf("%lld\n",G(n));
  61. }
  62. }
  63. }

一切从头开始,我们学习反演还有这些东西的初衷是想要降低单次回答的复杂度,看到原来的问题:

$ G(n) = \sum\limits_{i=1}{n-1}\sum\limits_{j=i+1}{n} gcd(i,j) \(
交换求和,这个没问题:
\) G(n) = \sum\limits_{j=2}{n}\sum\limits_{i=1}{j-1} gcd(i,j) $

记 $ H(n) = \sum\limits_{i=1}^{n-1} gcd(i,n) $

原式 \(G(n) = \sum\limits_{j=2}^{n} H(j)\)

貌似 \(H(n)\) 好像似曾相识? $ H(n) = ( \sum\limits_{i=1}^{n} gcd(i,n) ) - n$

里面这个不是前几天处理过?这种 \(gcd\) 就只可能是 \(n\) 的因子:

$ H(n) = ( \sum\limits_{d|n} d \sum\limits_{i=1}^{n} [gcd(i,n)d] ) - n$

$ H(n) = ( \sum\limits_{d|n} d \sum\limits_{i=1}^{\frac{n}{d}} [gcd(i,\frac{n}{d})1] ) - n$

$ H(n) = ( \sum\limits_{d|n} d \varphi(\frac{n}{d}) ) - n$

为方便,记 $ h(n) = \sum\limits_{d|n} d \varphi(\frac{n}{d}) $

意思是这个 \(h(n)\) 可以用埃筛,那么这个问题到这里就解决了,但是会不会有线筛的做法呢?

这个 \(id*\varphi\) 狄利克雷卷积在这里处理过。

那么来一波线性的做法:

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. typedef long long ll;
  4. const int MAXN=1000000;
  5. int prime[MAXN+1];
  6. int &ptop=prime[0];
  7. ll h[MAXN+1];
  8. int pk[MAXN+1];
  9. inline void sieve(){
  10. const int &n=MAXN;
  11. for(int i=2;i<=n;i++){
  12. if(!pk[i]){
  13. ptop++;
  14. prime[ptop]=i;
  15. pk[i]=i;
  16. h[i]=i+i-1;
  17. }
  18. for(int j=1;j<=ptop;j++){
  19. int &p=prime[j];
  20. int t=i*p;
  21. if(t>n)
  22. break;
  23. if(i%p){
  24. pk[t]=pk[p];
  25. h[t]=h[i]*h[p];
  26. }
  27. else{
  28. pk[t]=pk[i]*p;
  29. if(pk[t]==t){
  30. h[t]=(t-i)+h[i]*p;
  31. }else{
  32. h[t]=h[pk[t]]*h[t/pk[t]];
  33. }
  34. break;
  35. }
  36. }
  37. }
  38. for(int i=1;i<=n;i++){
  39. h[i]-=i;
  40. }
  41. for(int i=1;i<=n;i++){
  42. h[i]+=h[i-1];
  43. }
  44. }
  45. inline ll G(int n){
  46. ll res=h[n]-h[1];
  47. return res;
  48. }
  49. int main() {
  50. #ifdef Yinku
  51. freopen("Yinku.in","r",stdin);
  52. #endif // Yinku
  53. sieve();
  54. int n;
  55. while(~scanf("%d",&n)){
  56. if(n==0)
  57. break;
  58. else{
  59. printf("%lld\n",G(n));
  60. }
  61. }
  62. }

洛谷 - SP3871 GCDEX - GCD Extreme - 莫比乌斯反演的更多相关文章

  1. 洛谷 P5518 - [MtOI2019]幽灵乐团 / 莫比乌斯反演基础练习题(莫比乌斯反演+整除分块)

    洛谷题面传送门 一道究极恶心的毒瘤六合一题,式子推了我满满两面 A4 纸-- 首先我们可以将式子拆成: \[ans=\prod\limits_{i=1}^A\prod\limits_{j=1}^B\p ...

  2. [洛谷P1390]公约数的和·莫比乌斯反演

    公约数的和 传送门 分析 这道题很显然答案为 \[Ans=\sum_{i=1}^n\sum_{j=i+1}^n (i,j)\] //其中\((i,j)\)意味\(gcd(i,j)\) 这样做起来很烦, ...

  3. 洛谷 - P4449 - 于神之怒加强版 - 莫比乌斯反演

    https://www.luogu.org/problemnew/show/P4449 \(F(n)=\sum\limits_{i=1}^{n}\sum\limits_{i=1}^{m} gcd(i, ...

  4. 洛谷P2522 [HAOI2011]Problem b(莫比乌斯反演)

    题目描述 对于给出的n个询问,每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d,且gcd(x,y) = k,gcd(x,y)函数为x和y的最大公约数. 输入输出格式 输入格式: 第一行一个整数 ...

  5. 洛谷P3455 [POI2007]ZAP-Queries (莫比乌斯反演)

    题意:求$\sum_{i=1}^{a}\sum_{j=1}^{b}[gcd(i,j)==d]$(1<=a,b,d<=50000). 很套路的莫比乌斯反演. $\sum_{i=1}^{n}\ ...

  6. 洛谷P3768 简单的数学题 莫比乌斯反演+杜教筛

    题意简述 求出这个式子 \[ \sum_{i=1}^n\sum_{j=1}^n ij(i,j) \bmod p \] 做法 先用莫比乌斯反演拆一下式子 \[ \begin{split} \sum_{i ...

  7. 洛谷P3455 [POI2007]ZAP-Queries(莫比乌斯反演)

    传送门 设$$f(k)=\sum_{i=1}^{a}\sum_{j=1}^{b}[gcd(i,j)=k]$$ $$g(n)=\sum_{n|k}f(k)=\lfloor\frac{a}{n}\rflo ...

  8. 洛谷 - P1390 - 公约数的和 - 莫比乌斯反演 - 欧拉函数

    https://www.luogu.org/problemnew/show/P1390 求 $\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m} gcd(i,j) $ ...

  9. 洛谷P3312 [SDOI2014]数表(莫比乌斯反演+树状数组)

    传送门 不考虑$a$的影响 设$f(i)$为$i$的约数和 $$ans=\sum\limits_{i=1}^n\sum\limits_{j=1}^nf(gcd(i,j))$$ $$=\sum\limi ...

随机推荐

  1. MySQL 数据类型转换

    版权个人所有,欢迎转载如转载请说明出处.(东北大亨) http://www.cnblogs.com/northeastTycoon/p/5505523.html 网络越来越达到所以带来的好处不容置疑. ...

  2. 二维码、条形码扫描——使用Google ZXing

    我在项目中用到了二维码扫描的技术,用的是Google提供的ZXing开源项目,它提供二维码和条形码的扫描.扫描条形码就是直接读取条形码的内容,扫描二维码是按照自己指定的二维码格式进行编码和解码. 可以 ...

  3. EasyPusher直播推送中用到的缓冲区设计和丢帧原理

    问题描述 我们在开发直播过程中,会需要用到直播推送端,推送端将直播的音视频数据推送到流媒体服务器或者cdn,再由流媒体服务器/CDN进行视频的转发和分发,提供给客户端进行观看.由于直播推送端会存在于各 ...

  4. 公网RTSP地址(持续更新)

    H264+AAC: rtsp://a2047.v1412b.c1412.g.vq.akamaistream.net/5/2047/1412/1_h264_350/1a1a1ae555c53196016 ...

  5. input光标位置

    兼容谷歌火狐-input光标位置 input框在没有添加任何效果的情况下,输入文字后光标始终在最后的位置,谷歌||火狐效果一样 但是在给input加入点击事件后 谷歌:input框插入文字后,光标会自 ...

  6. mongodb的锁和高并发

    1 mongodb的锁 mongodb使用的读写锁. 2 mongodb高并发 同样是读写锁造成的问题. 3 findandmodify 该操作是原子的.

  7. non-blocking I/O

    https://en.wikipedia.org/wiki/New_I/O_(Java) zh.wikipedia.org/wiki/Java_NIO Java NIO API提供在java.nio套 ...

  8. ORACLE函数之单行转换函数

     1           ASCIISTR 格式:ASCIISTR(C) 说明:将字符串C转换为ASCII字符串,即将C中的ASCII字符保留不变,但非ASCII字符则以ASCII表示返回 举例: ...

  9. 【LeetCode】Sqrt(x) (转载)

    Implement int sqrt(int x). Compute and return the square root of x. 原文地址: http://kb.cnblogs.com/page ...

  10. contentprovider基础

    程序启动后,只要再manifest当中注册上,就会执行PersonProvider()创建一个对象