题目

给定正整数n,m。求

输入格式

一行两个整数n,m。

输出格式

一个整数,为答案模1000000007后的值。

输入样例

5 4

输出样例

424

提示

数据规模:

1<=n,m<=500000,共有3组数据。

题解

套路反演:

\[\begin{aligned}
ans &= \sum\limits_{d = 1}^{n} \sum\limits_{i = 1}^{\lfloor \frac{n}{d} \rfloor} \sum\limits_{j = 1}^{\lfloor \frac{m}{d} \rfloor} (\frac{id * jd}{d})^{d} \qquad [gcd(i,j) == 1] \\
&= \sum\limits_{d = 1}^{n} d^{d} \sum\limits_{i = 1}^{\lfloor \frac{n}{d} \rfloor} \sum\limits_{j = 1}^{\lfloor \frac{m}{d} \rfloor} i^{d}j^{d} \qquad [gcd(i,j) == 1] \\
&= \sum\limits_{d= 1}^{n} d^{d} \sum\limits_{k = 1}^{\lfloor \frac{n}{d} \rfloor} \mu(k) k^{2d} \sum\limits_{i = 1}^{\lfloor \frac{n}{kd} \rfloor} i^{d} \sum\limits_{j = 1}^{\lfloor \frac{m}{kd} \rfloor} j^{d}
\end{aligned}
\]

然后就慌了,好像搞不下去了

仔细分析一下复杂度,对于每个\(d\),里面那堆玩意只需要\(O(\lfloor \frac{m}{d} \rfloor)\)就可以计算出来

所以复杂度为\(n\)乘一个调和级数

即\(O(nlogn)\)

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#define LL long long int
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define BUG(s,n) for (int i = 1; i <= (n); i++) cout<<s[i]<<' '; puts("");
using namespace std;
const int maxn = 500005,maxm = 100005,INF = 1000000000,P = 1e9 + 7;
int p[maxn],isn[maxn],pi,mu[maxn],n,m;
LL a[maxn],sum[maxn];
LL qpow(LL a,LL b){
LL ans = 1;
for (; b; b >>= 1, a = a * a % P)
if (b & 1) ans = ans * a % P;
return ans;
}
void init(){
mu[1] = 1;
for (int i = 2; i <= n; i++){
if (!isn[i]) p[++pi] = i,mu[i] = -1;
for (int j = 1; j <= pi && i * p[j] <= n; j++){
isn[i * p[j]] = true;
if (i % p[j] == 0){
mu[i * p[j]] = 0;
break;
}
mu[i * p[j]] = -mu[i];
}
}
}
int main(){
scanf("%d%d",&n,&m);
if (n > m) swap(n,m);
init();
REP(i,m) a[i] = 1;
LL ans = 0;
for (int d = 1; d <= n; d++){
for (LL i = 1; i <= m / d; i++){
a[i] = a[i] * i % P;
sum[i] = (sum[i - 1] + a[i]) % P;
}
LL tmp = 0;
for (int k = 1; k <= n / d; k++){
tmp = (tmp + (mu[k] * qpow(k,2 * d) % P + P) % P * sum[n / (k * d)] % P * sum[m / (k * d)] % P);
tmp = (tmp + P) % P;
}
ans = (ans + qpow(d,d) * tmp % P) % P;
}
ans = (ans % P + P) % P;
printf("%lld\n",ans);
return 0;
}

最新文章

  1. java中File类的使用
  2. NHibernate生成实体类、xml映射文件
  3. Spire.Office组件使用例子
  4. 什么是purge操作
  5. ci默认控制器
  6. jquery animate()方法使用的注意事项
  7. javascripct字符串
  8. Smarty 插件开发
  9. codeforces 340E Iahub and Permutations(错排or容斥)
  10. 大数据学习系列之七 ----- Hadoop+Spark+Zookeeper+HBase+Hive集群搭建 图文详解
  11. c语言函数实参与形参整理
  12. angular 选中切换面板
  13. 判断ssh远程命令是否执行结束
  14. 点击table中的某一个td,获得这个tr的所有数据
  15. mac 连接linux服务器,用scp命令实现本地文件与服务器文件之间的互相传输
  16. SS-QT5
  17. Day 1: ASP.NET and JavaScript Jan.16th Trying
  18. edit this cookie chrome插件 (HttpAnalyzerStdV3 获取Cookie 后,再用edit this cookie添加cookie)
  19. Oracle 11.2.0.4.0 Dataguard部署和日常维护(3)-Datauard监控篇
  20. VMware进入BIOS

热门文章

  1. pycharm 安装插件 支持markdown
  2. spring xml 配置文件中标签的解析
  3. 20180911 关于页面加载顺序引发的JS的undefined/null错误
  4. 如何在vue项目中使用md5加密
  5. grep过滤目录或文件方法
  6. arduino 语音音箱 :语音控制、MP3播放、报时、回复温湿度情况
  7. 初学puppet
  8. LeetCode949-给定数字能组成的最大时间
  9. 绘制弧形:imagearc() 说明:三点钟的位置是起点(0度
  10. libevent 信号事件实现方式