原文链接http://www.cnblogs.com/zhouzhendong/p/8116330.html

UPD(2018-03-26):回来重新学数论啦。之前的博客版面放在更新之后的后面。


题目传送门 - BZOJ3561


题意概括

  给出$n,m$,求$\Large\sum_{i=1}^n\sum_{j=1}^m lcm(i,j)^{\gcd(i, j)}$。

  $1\leq n,m\leq 500000$

题解

  先推式子:(假设$n\leq m$)

  $$\sum_{i=1}^n\sum_{j=1}^m lcm(i,j)^{\gcd(i, j)}\\=\sum_{d=1}^{n}\sum_{i=1}^{\left\lfloor\frac nd\right\rfloor}\sum_{j=1}^{\left\lfloor\frac md\right\rfloor}(ijd)^d\cdot[\gcd(i,j)=1]\\=\sum_{d=1}^{n}\sum_{i=1}^{\left\lfloor\frac nd\right\rfloor}\sum_{j=1}^{\left\lfloor\frac md\right\rfloor}(ijd)^d\cdot\sum_{p|i,p|j}\mu(p)\\=\sum_{d=1}^{n}d^{d}\sum_{p=1}^{\left\lfloor\frac nd\right\rfloor}\mu(p)\sum_{i=1}^{\left\lfloor\frac{n}{pd}\right\rfloor}\sum_{j=1}^{\left\lfloor\frac{m}{pd}\right\rfloor}(ijp^2)^d\\=\sum_{d=1}^{n}d^{d}\sum_{p=1}^{\left\lfloor\frac nd\right\rfloor}\mu(p)p^{2d}\sum_{i=1}^{\left\lfloor\frac {n}{pd}\right\rfloor}i^d\sum_{j=1}^{\left\lfloor\frac{m}{pd}\right\rfloor}j^d$$

  然后发现对于$d^d$可以直接快速幂。对于某一个$d$,要枚举的$p$有$O(\frac nd)$个,对于后面的一堆数的幂和,只要前缀和预处理,要处理的个数也是$O(\frac md)$的。所以总复杂度为$O(n \log n)$。

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=500005;
const LL mod=1e9+7;
int n,m,prime[N],u[N],pcnt=0;
bool f[N];
void init(int n){
memset(f,true,sizeof f);
f[0]=f[1]=0,u[1]=1;
for (int i=2;i<=n;i++){
if (f[i])
prime[++pcnt]=i,u[i]=-1;
for (int j=1;j<=pcnt&&i*prime[j]<=n;j++){
f[i*prime[j]]=0;
if (i%prime[j])
u[i*prime[j]]=-u[i];
else {
u[i*prime[j]]=0;
break;
}
}
}
}
LL Pow(LL x,LL y){
if (!y)
return 1LL;
LL xx=Pow(x,y/2);
xx=xx*xx%mod;
if (y&1LL)
xx=xx*x%mod;
return xx;
}
LL pows[N],sum[N];
int main(){
scanf("%d%d",&n,&m);
if (n>m)
swap(n,m);
init(n);
for (int i=1;i<=m;i++)
pows[i]=1;
LL ans=0;
for (int d=1;d<=n;d++){
LL now=0;
sum[0]=0;
for (int i=1;i<=m/d;i++)
pows[i]=pows[i]*i%mod,sum[i]=(sum[i-1]+pows[i])%mod;
for (int p=1;p<=n/d;p++)
now=(now+u[p]*pows[p]*pows[p]%mod*sum[n/p/d]%mod*sum[m/p/d])%mod;
now=(now%mod+mod)%mod;
ans=(ans+Pow(d,d)*now)%mod;
}
printf("%lld",ans);
return 0;
}

  

——————old——————

题意概括

给定正整数n,m。求
 

题解

博主越来越懒了。

http://blog.csdn.net/lych_cys/article/details/50721642?locationNum=1&fps=1


代码

#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long LL;
const int N=500005;
const LL mod=1e9+7;
LL n,m,u[N],prime[N],pcnt,v[N],sum[N];
bool isprime[N];
LL Pow(LL x,LL y){
if (y==0)
return 1LL;
LL xx=Pow(x,y/2);
xx=xx*xx%mod;
if (y&1LL)
xx=xx*x%mod;
return xx;
}
void Get_Mobius(){
memset(isprime,true,sizeof isprime);
isprime[0]=isprime[1]=pcnt=0;
u[1]=1;
for (LL i=2;i<=n;i++){
if (isprime[i])
u[i]=-1,prime[++pcnt]=i;
for (LL j=1;j<=pcnt&&i*prime[j]<=n;j++){
isprime[i*prime[j]]=0;
if (i%prime[j])
u[i*prime[j]]=-u[i];
else {
u[i*prime[j]]=0;
break;
}
}
}
}
int main(){
scanf("%lld%lld",&n,&m);
if (n<m)
swap(n,m);
Get_Mobius();
for (int i=1;i<=n;i++)
v[i]=1;
LL ans=0;
for (LL d=1;d<=m;d++){
sum[0]=0;
for (LL i=1;i<=(LL)(n/d);i++)
v[i]=v[i]*i%mod,sum[i]=(v[i]+sum[i-1])%mod;
LL res=0;
for (LL p=1;p<=(LL)(m/d);p++)
res=(res+v[p]*v[p]%mod*u[p]*sum[n/d/p]%mod*sum[m/d/p]%mod+mod)%mod;
ans=(ans+res*Pow(d,d))%mod;
}
printf("%lld",ans);
return 0;
}

  

最新文章

  1. Oracle建表添加数据
  2. C++多线程开发之actor model
  3. SQL 报错信息整理及解决方案(持续更新)
  4. [原]Android Studio查询SHA1的方法
  5. cygwin中运行命令提示command not found的解决方法
  6. python【第十五篇】JavaScript
  7. 小鱼提问3 static方法中可以访问某个类的私有变量吗(不通过反射的其他非正常手段)?什么情况下可以?
  8. 从实战出发,谈谈 nginx 信号集
  9. 从零开始学习前端开发 — 15、CSS3过渡、动画
  10. [SDOI 2015]序列统计
  11. InnoSetup 客户端程序打包教程
  12. 遍历二叉树 traversing binary tree 线索二叉树 threaded binary tree 线索链表 线索化
  13. redis 集群模式安装
  14. 弹指之间 -- Polychord
  15. linux笔记_day03
  16. Atitit xml框架类库选型 attilax总结
  17. 在AspNetCore 中 使用Redis实现分布式缓存 (转载)
  18. crontab入门
  19. Nginx SSL配置
  20. Django学习笔记--通用列表和详细信息视图

热门文章

  1. 解决FTPClient上传文件为空,显示0字节
  2. CentOS 7 服务器之间ssh无密码登录、传输文件
  3. vi快速查找
  4. swift 实践- 02 -- 自定义cell 的简单使用
  5. Linux 上的 SQL Server 2017 的安装指南
  6. SpringMvc + Jsp+ 富文本 kindeditor 进行 图片ftp上传nginx服务器 实现
  7. (七)STL适配器
  8. centos忘记密码
  9. ftp的自动部署以及添加虚拟账户的脚本
  10. axure—日期函数