求:

\(S(n,m)=\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}lcm(i,j)\)

显然:

\(S(n,m)=\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}\frac{ij}{gcd(i,j)}\)

枚举g:

\(S(n,m)=\sum\limits_{g=1}^{n}\frac{1}{g}\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}ij[gcd(i,j)==g]\)

除以g:

\(S(n,m)=\sum\limits_{g=1}^{n}g\sum\limits_{i=1}^{\lfloor\frac{n}{g}\rfloor}\sum\limits_{j=1}^{\lfloor\frac{m}{g}\rfloor}ij[gcd(i,j)==1]\)

记:

\(S_1(n,m)=\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}ij[gcd(i,j)==1]\)

原式:

\(S(n,m)=\sum\limits_{g=1}^{n}gS_1(\lfloor\frac{n}{g}\rfloor,\lfloor\frac{m}{g}\rfloor)\)

化简\(S_1(n,m)\),显然:

\(S_1(n,m)=\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}ij\sum\limits_{k|gcd(i,j)}\mu(k)\)

枚举k:

\(S_1(n,m)=\sum\limits_{k=1}^{min}\mu(k)\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}ij[k|gcd(i,j)]\)

显然:

\(S_1(n,m)=\sum\limits_{k=1}^{min}\mu(k)\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}ij[k|i][k|j]\)

这种时候可以除以k:

\(S_1(n,m)=\sum\limits_{k=1}^{min}\mu(k)k^2\sum\limits_{i=1}^{\lfloor\frac{n}{k}\rfloor}\sum\limits_{j=1}^{\lfloor\frac{m}{k}\rfloor}ij[1|i][1|j]\)

即:

\(S_1(n,m)=\sum\limits_{k=1}^{min}\mu(k)k^2\sum\limits_{i=1}^{\lfloor\frac{n}{k}\rfloor}\sum\limits_{j=1}^{\lfloor\frac{m}{k}\rfloor}ij\)

记:

\(S_2(n,m)=\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}ij\)

原式:

\(S_1(n,m)=\sum\limits_{k=1}^{min}\mu(k)k^2S_2(\lfloor\frac{n}{k}\rfloor,\lfloor\frac{m}{k}\rfloor)\)

显然:

\(S_2(n,m)=\sum\limits_{i=1}^{n}i\sum\limits_{j=1}^{m}j\)

即:

\(S_2(n,m)=\frac{1}{4}n(n+1)m(m+1)\)

时间复杂度:

求\(S_2(n,m)\)是\(O(1)\),分块求\(S_1(n,m)\)是\(O(n^{\frac{1}{2}})\)(大概),分块求\(S(n,m)\)是\(O(n)\)(大概)。

还需要线性筛出:\(\sum\limits_{k=1}^{min}\mu(k)k^2\)


线性筛已经足够了,还好写,不过为什么不试一波杜教筛呢?

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. typedef long long ll;
  4. const int mod=20101009;
  5. const int MAXN=1e7;
  6. int pri[MAXN+1];
  7. int &pritop=pri[0];
  8. int A[MAXN+1];
  9. int pk[MAXN+1];
  10. void sieve(int n=MAXN) {
  11. pk[1]=1;
  12. A[1]=1;
  13. for(int i=2; i<=n; i++) {
  14. if(!pri[i]) {
  15. pri[++pritop]=i;
  16. pk[i]=i;
  17. ll tmp=1ll*i*i;
  18. if(tmp>=mod)
  19. tmp%=mod;
  20. tmp=-tmp;
  21. if(tmp<mod)
  22. tmp+=mod;
  23. A[i]=tmp;
  24. }
  25. for(int j=1; j<=pritop; j++) {
  26. int &p=pri[j];
  27. int t=i*p;
  28. if(t>n)
  29. break;
  30. pri[t]=1;
  31. if(i%p) {
  32. pk[t]=p;
  33. ll tmp=1ll*A[i]*A[p];
  34. if(tmp>=mod)
  35. tmp%=mod;
  36. A[t]=tmp;
  37. } else {
  38. pk[t]=pk[i]*p;
  39. if(pk[t]==t) {
  40. A[t]=0;
  41. } else {
  42. ll tmp=1ll*A[t/pk[t]]*A[pk[t]];
  43. if(tmp>=mod)
  44. tmp%=mod;
  45. A[t]=tmp;
  46. }
  47. break;
  48. }
  49. }
  50. }
  51. for(int i=1; i<=n; i++) {
  52. A[i]+=A[i-1];
  53. if(A[i]>=mod)
  54. A[i]-=mod;
  55. }
  56. }
  57. inline int qpow(ll x,int n) {
  58. ll res=1;
  59. while(n) {
  60. if(n&1) {
  61. res*=x;
  62. if(res>=mod)
  63. res%=mod;
  64. }
  65. x*=x;
  66. if(x>=mod)
  67. x%=mod;
  68. n>>=1;
  69. }
  70. return res;
  71. }
  72. const int inv4=qpow(4,mod-2);
  73. inline int S2(int n,int m) {
  74. ll res=1ll*n*(n+1);
  75. if(res>=mod)
  76. res%=mod;
  77. res*=m;
  78. if(res>=mod)
  79. res%=mod;
  80. res*=(m+1);
  81. if(res>=mod)
  82. res%=mod;
  83. res*=inv4;
  84. if(res>=mod)
  85. res%=mod;
  86. return res;
  87. }
  88. inline int S1(int n,int m) {
  89. ll res=0;
  90. int nm=min(n,m);
  91. for(int l=1,r; l<=nm; l=r+1) {
  92. int tn=n/l;
  93. int tm=m/l;
  94. r=min(n/tn,m/tm);
  95. ll tmp=A[r]-A[l-1];
  96. if(tmp<0)
  97. tmp+=mod;
  98. tmp*=S2(tn,tm);
  99. if(tmp>=mod)
  100. tmp%=mod;
  101. res+=tmp;
  102. }
  103. if(res>=mod)
  104. res%=mod;
  105. return res;
  106. }
  107. inline int s1(int l,int r) {
  108. ll res=(1ll*(l+r)*(r-l+1))>>1;
  109. if(res>=mod)
  110. res%=mod;
  111. return res;
  112. }
  113. inline int S(int n,int m) {
  114. ll res=0;
  115. int nm=min(n,m);
  116. for(int l=1,r; l<=nm; l=r+1) {
  117. int tn=n/l;
  118. int tm=m/l;
  119. r=min(n/tn,m/tm);
  120. ll tmp=s1(l,r);
  121. tmp*=S1(tn,tm);
  122. if(tmp>=mod)
  123. tmp%=mod;
  124. res+=tmp;
  125. }
  126. if(res>=mod)
  127. res%=mod;
  128. return res;
  129. }
  130. int main() {
  131. #ifdef Yinku
  132. freopen("Yinku.in","r",stdin);
  133. #endif // Yinku
  134. int n,m;
  135. scanf("%d%d",&n,&m);
  136. sieve(max(n,m));
  137. printf("%d\n",S(n,m));
  138. return 0;
  139. }

杜教筛还是非常快的。

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. typedef long long ll;
  4. const int mod=20101009;
  5. //杜教筛
  6. const int MAXN=pow(1e7,2.0/3.0)+1;
  7. int pri[MAXN+1];
  8. int &pritop=pri[0];
  9. int A[MAXN+1];
  10. int pk[MAXN+1];
  11. void sieve(int n=MAXN) {
  12. pk[1]=1;
  13. A[1]=1;
  14. for(int i=2; i<=n; i++) {
  15. if(!pri[i]) {
  16. pri[++pritop]=i;
  17. pk[i]=i;
  18. ll tmp=1ll*i*i;
  19. if(tmp>=mod)
  20. tmp%=mod;
  21. tmp=-tmp;
  22. if(tmp<mod)
  23. tmp+=mod;
  24. A[i]=tmp;
  25. }
  26. for(int j=1; j<=pritop; j++) {
  27. int &p=pri[j];
  28. int t=i*p;
  29. if(t>n)
  30. break;
  31. pri[t]=1;
  32. if(i%p) {
  33. pk[t]=p;
  34. ll tmp=1ll*A[i]*A[p];
  35. if(tmp>=mod)
  36. tmp%=mod;
  37. A[t]=tmp;
  38. } else {
  39. pk[t]=pk[i]*p;
  40. if(pk[t]==t) {
  41. A[t]=0;
  42. } else {
  43. ll tmp=1ll*A[t/pk[t]]*A[pk[t]];
  44. if(tmp>=mod)
  45. tmp%=mod;
  46. A[t]=tmp;
  47. }
  48. break;
  49. }
  50. }
  51. }
  52. for(int i=1; i<=n; i++) {
  53. A[i]+=A[i-1];
  54. if(A[i]>=mod)
  55. A[i]-=mod;
  56. }
  57. }
  58. inline int qpow(ll x,int n) {
  59. ll res=1;
  60. while(n) {
  61. if(n&1) {
  62. res*=x;
  63. if(res>=mod)
  64. res%=mod;
  65. }
  66. x*=x;
  67. if(x>=mod)
  68. x%=mod;
  69. n>>=1;
  70. }
  71. return res;
  72. }
  73. const int inv4=qpow(4,mod-2);
  74. inline int S2(int n,int m) {
  75. ll res=1ll*n*(n+1);
  76. if(res>=mod)
  77. res%=mod;
  78. res*=m;
  79. if(res>=mod)
  80. res%=mod;
  81. res*=(m+1);
  82. if(res>=mod)
  83. res%=mod;
  84. res*=inv4;
  85. if(res>=mod)
  86. res%=mod;
  87. return res;
  88. }
  89. const int inv6=qpow(6,mod-2);
  90. inline int s2(int n) {
  91. ll res=1ll*n*(n+1);
  92. if(res>=mod)
  93. res%=mod;
  94. res*=(2ll*n+1);
  95. if(res>=mod)
  96. res%=mod;
  97. res*=inv6;
  98. if(res>=mod)
  99. res%=mod;
  100. return res;
  101. }
  102. unordered_map<int,int> GA;
  103. inline int Get_A(int n){
  104. if(n<=MAXN)
  105. return A[n];
  106. if(GA.count(n))
  107. return GA[n];
  108. ll res=1;
  109. for(int l=2,r;l<=n;l=r+1){
  110. int t=n/l;
  111. r=n/t;
  112. ll tmp=s2(r)-s2(l-1);
  113. if(tmp<0)
  114. tmp+=mod;
  115. tmp*=Get_A(t);
  116. if(tmp>=mod)
  117. tmp%=mod;
  118. res-=tmp;
  119. }
  120. res%=mod;
  121. if(res<0)
  122. res+=mod;
  123. return GA[n]=res;
  124. }
  125. inline int S1(int n,int m) {
  126. ll res=0;
  127. int nm=min(n,m);
  128. for(int l=1,r; l<=nm; l=r+1) {
  129. int tn=n/l;
  130. int tm=m/l;
  131. r=min(n/tn,m/tm);
  132. ll tmp=Get_A(r)-Get_A(l-1);
  133. if(tmp<0)
  134. tmp+=mod;
  135. tmp*=S2(tn,tm);
  136. if(tmp>=mod)
  137. tmp%=mod;
  138. res+=tmp;
  139. }
  140. if(res>=mod)
  141. res%=mod;
  142. return res;
  143. }
  144. inline int s1(int l,int r) {
  145. ll res=(1ll*(l+r)*(r-l+1))>>1;
  146. if(res>=mod)
  147. res%=mod;
  148. return res;
  149. }
  150. inline int S(int n,int m) {
  151. ll res=0;
  152. int nm=min(n,m);
  153. for(int l=1,r; l<=nm; l=r+1) {
  154. int tn=n/l;
  155. int tm=m/l;
  156. r=min(n/tn,m/tm);
  157. ll tmp=s1(l,r);
  158. tmp*=S1(tn,tm);
  159. if(tmp>=mod)
  160. tmp%=mod;
  161. res+=tmp;
  162. }
  163. if(res>=mod)
  164. res%=mod;
  165. return res;
  166. }
  167. int main() {
  168. #ifdef Yinku
  169. freopen("Yinku.in","r",stdin);
  170. #endif // Yinku
  171. int n,m;
  172. scanf("%d%d",&n,&m);
  173. sieve();
  174. printf("%d\n",S(n,m));
  175. return 0;
  176. }

洛谷 - P1829 - Crash的数字表格 - 莫比乌斯反演的更多相关文章

  1. bzoj2154||洛谷P1829 Crash的数字表格&&JZPTAB && bzoj3309 DZY Loves Math

    bzoj2154||洛谷P1829 https://www.lydsy.com/JudgeOnline/problem.php?id=2154 https://www.luogu.org/proble ...

  2. [BZOJ 2154]Crash的数字表格(莫比乌斯反演+数论分块)

    [BZOJ 2154]Crash的数字表格(莫比乌斯反演+数论分块) 题面 求 \[\sum_{i=1}^{n} \sum_{j=1}^{m} \mathrm{lcm}(i,j)\] 分析 \[\su ...

  3. BZOJ 2154: Crash的数字表格 [莫比乌斯反演]

    2154: Crash的数字表格 Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 2924  Solved: 1091[Submit][Status][ ...

  4. [bzoj 2693] jzptab & [bzoj 2154] Crash的数字表格 (莫比乌斯反演)

    题目描述 TTT组数据,给出NNN,MMM,求∑x=1N∑y=1Mlim(x,y)\sum_{x=1}^N\sum_{y=1}^M lim(x,y)\newlinex=1∑N​y=1∑M​lim(x, ...

  5. 【bzoj2154】Crash的数字表格 莫比乌斯反演

    题目描述 今天的数学课上,Crash小朋友学习了最小公倍数(Least Common Multiple).对于两个正整数a和b,LCM(a, b)表示能同时被a和b整除的最小正整数.例如,LCM(6, ...

  6. 【BZOJ】2154: Crash的数字表格 莫比乌斯反演

    [题意]给定n,m,求Σlcm(i,j),1<=i<=n,1<=j<=m,n,m<=10^7. [算法]数论(莫比乌斯反演) [题解] $$ans=\sum_{i\leq ...

  7. bzoj2154: Crash的数字表格 莫比乌斯反演

    题意:求\(\sum_{i=1}^n \sum_{j=1}^m\frac{i*j}{gcd(i,j)}\) 题解:\(ans=\sum_{i=1}^n\sum_{j=1}^m \frac{i*j}{g ...

  8. BZOJ 2154 Crash的数字表格 ——莫比乌斯反演

    求$\sum_{i=1}^n\sum_{j=1}^n lcm(i,j)$ 枚举因数 $ans=\sum_{d<=n} F(d) * d$ $F(d)$表示给定范围内两两$\sum_{gcd(i, ...

  9. [国家集训队] Crash的数字表格 - 莫比乌斯反演,整除分块

    考虑到\(lcm(i,j)=\frac{ij}{gcd(i,j)}\) \(\sum_{i=1}^n\sum_{j=1}^m\frac{ij}{gcd(i,j)}\) \(\sum_{d=1}^{n} ...

随机推荐

  1. vim 插件: ctrlp.vim

    vim-scripts 里可以搜到这个插件. 安装好了之后,在 vim 的 normal 模式之下按 Ctrl+P 组合键即可弹出搜索窗口. * <f5> 更新目录缓存. * <c- ...

  2. 安装protobuf可能遇到的问题

    下载protobuf-2.3.0:    http://protobuf.googlecode.com/files/protobuf-2.3.0.zip http://code.google.com/ ...

  3. Android 向右滑动销毁(finish)Activity, 随着手势的滑动而滑动的效果

    http://blog.csdn.net/xiaanming/article/details/20934541

  4. cocos2d-x lua 中使用protobuf并对http进行处理

    cocos2d-x lua 中使用protobuf并对http进行处理 本文介绍 cocos2d-x lua 中使用http 和 基于cocos2d-x 对lua http的封装(部分ok) 本博客链 ...

  5. delphi android 录像(使用了JMediaRecorder,MediaRecorder的使用方法)

    delphi xe系列自带的控件都无法保存录像,经网友帮忙,昨天终于实现了录像功能(但有个问题是录像时无画面显示),程序主要使用了JMediaRecorder,MediaRecorder的使用方法可参 ...

  6. log4j(转)

    让System.out.println回家种田,换句话说,就是该干嘛干嘛去. 您可能在想: System.out.println几乎在每个Java程序里都有那么几行,如何让他老人家回家种田呢? 我们怎 ...

  7. 人生苦短之Python装饰器

    在Python中函数也是一个对象,我们可以获得函数对象,然后执行函数 def func(): print('I am very good') a = func a 如果我们要是想增强这个函数呢?比如给 ...

  8. RobotFramework教程使用笔记——初识RobotFramework

    1.创建项目 File->New Project 创建测试项目 Type选择Directory 右键项目创建测试套件,也可以理解为创建不同测试逻辑或者是测试业务 右键测试套件创建case 注:如 ...

  9. 网络测试常用的命令-比较ping,tracert和pathping等命令之间的关系

    无论你是一个网络维护人员,还是正在学习TCP/IP协议,了解和掌握一些常用的网络测试命令将会有助于您更快地检测到网络故障所在,同时也会有助你您了解网络通信的内幕. 下面我们逐步介绍几个常用的命令: 1 ...

  10. Program received signal SIGSEGV, Segmentation fault.

    GDB调试的时候出现了: Program received signal SIGSEGV, Segmentation fault.(程序收到信号SIGSEGV,分段故障) SIGSEGV:在POSIX ...