正题

题目链接:http://www.ybtoj.com.cn/contest/122/problem/3


题目大意

\(S(i)\)表示\(i\)的约数个数,\(Q\)次询问给出\(n,m\)求

\[\sum_{a=1}^n\sum_{b=1}^mS(a^2)\times S(b^2)\times S(a\times b)
\]

\(1\leq Q\leq 10^4,1\leq n,m\leq 2\times 10^5\)


解题思路

前面的推式子挺套路的

首先我们要搞定\(S(n^2)\)这个东西,一个经典的结论就是\(S(n\times m)=\sum_{i|n}\sum_{j|m}[gcd(i,j)=1]\)。莫反一下就有

\[S(a\times b)=\sum_{d|(a\times b)}\mu(d)\sum_{i\times d|a}\sum_{j\times d|b}1
\]

所以就有

\[S(n^2)=\sum_{d|n}\mu(d)S(\frac{n}{d})^2
\]

用线性筛筛出前面的\(S\),然后\(O(n\log n)\)求出\(h(n)=S(n^2)\)

然后化一下式子

\[\sum_{a=1}^n\sum_{b=1}^mh(a)\times h(b)\sum_{i|a}\sum_{j|b}[gcd(i,j)=1]
\]
\[\sum_{d=1}\mu(d)(\sum_{d|i}\sum_{i|a}h(a))(\sum_{d|j}\sum_{j|b}h(b))
\]
\[\sum_{d=1}\mu(d)(\sum_{d|a}S(\frac{a}{d})h(a))(\sum_{d|b}S(\frac{b}{d})h(b))
\]

然后就好像没得化简了,先处理出\(F(d,n)=\sum_{i=1}^nh(i\times d)S(i)\)

发现\(d\)很大的时候后面那个东西的取值就很小,但是\(d\)很多,需要快速处理。

设定一个分界值\(T\),每次小于\(T\)的部分我们就暴力用\(F\)数组计算,大于\(T\)的部分我们预处理出一个

\[G(d,i,j)=\sum_{x=T+1}^dF(i)F(j)\mu(d)
\]

然后整除分块计算。

这里的\(k\)取\(N^{\frac{2}{3}}\)会平均一些,时间复杂度\(O(n^{\frac{4}{3}}+Qn^{\frac{2}{3}})\)


code

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#define ll long long
using namespace std;
const ll N=2e5+10,P=1<<30;
ll q,n,m,cnt,pri[N],mu[N],S[N],sg[N],g[N],o[N];
vector<int>f[N],d[N];
bool v[N];
void prime(){
mu[1]=sg[1]=1;
for(ll i=2;i<N;i++){
if(!v[i])pri[++cnt]=i,mu[i]=-1,g[i]=2,sg[i]=2;
for(ll j=1;j<=cnt&&i*pri[j]<N;j++){
v[i*pri[j]]=1;
if(i%pri[j]==0){
g[i*pri[j]]=g[i]+1;
sg[i*pri[j]]=sg[i]/g[i]*g[i*pri[j]];
break;
}
mu[i*pri[j]]=-mu[i];g[i*pri[j]]=2;
sg[i*pri[j]]=sg[i]*sg[pri[j]];
}
}
for(ll i=1;i<N;i++)
for(ll j=i;j<N;j+=i)
(S[j]+=sg[j/i]*sg[j/i]*mu[i]%P)%=P;
return;
}
signed main()
{
freopen("math.in","r",stdin);
freopen("math.out","w",stdout);
prime();
scanf("%lld",&q);ll lim=2e5;
ll T=(ll)pow(lim,2.0/3.0)+1;
f[0].resize(lim+1);
for(ll i=1;i<=lim;i++){
f[i].push_back(0);
for(ll j=1;j<=lim/i;j++){
ll tmp=f[i][j-1];
f[i].push_back((tmp+S[i*j]*sg[j])%P);
}
}
d[T].resize((lim/T)*(lim/T)+1);
for(ll i=T+1;i<=lim;i++){
ll p=lim/i;
d[i].resize(p*p+1);
for(ll j=1,sum=0;j<=lim/i;j++)
for(ll k=j;k<=lim/i;k++)
d[i][(j-1)*p+k]=(d[i-1][(j-1)*o[i-1]+k]+f[i][j]*f[i][k]*mu[i])%P;
o[i]=p;
}
while(q--){
scanf("%lld%lld",&n,&m);
if(n>m)swap(n,m);ll ans=0;
for(ll i=1;i<=min(T,n);i++)
(ans+=1ll*f[i][n/i]*f[i][m/i]*mu[i]%P)%=P;
for(ll l=T+1,r;l<=n;l=r+1){
r=min(n/(n/l),m/(m/l));
(ans+=d[r][(n/l-1)*o[r]+m/l]-d[l-1][(n/l-1)*o[l-1]+m/l])%=P;
}
printf("%lld\n",(ans+P)%P);
}
return 0;
}

最新文章

  1. redis慢查询日志
  2. XSS攻击
  3. MHA故障切换和在线手工切换原理
  4. python抓取某学院视频
  5. Azure REST API (2) Azure Storage
  6. create mystic by Django
  7. Informatica Powercenter学习笔记
  8. 腾讯微博数据抓取(java实现)
  9. Mysql 授权访问
  10. 网站项目:让一般处理文件.ashx的代码有折叠功能(#region)
  11. 爱斯达M2C服装定制系统介绍—在线播放—优酷网,视频高清在线观看
  12. logrotate 日志清理后 rsyslog中断问题
  13. thinkphp学习笔记6—url模式
  14. linq to NHibernate
  15. ViewPager无限轮播与自定义切换动画
  16. utl_file包的使用
  17. CSS布局十八般武艺都在这里了
  18. 谈谈我理解的SA——Systems Architecture
  19. about this blog
  20. springcloud第四步:ribbon搭建服务负载均衡

热门文章

  1. mpvue学习笔记
  2. SQL:多表查询
  3. MVVMLight学习笔记(四)---RelayCommand初探
  4. Centos7 安装 redis4.x
  5. linux下设备驱动的结构&amp;编译&amp;加载
  6. Spring中常用重要的接口
  7. linux 常用命令(三)——(centos7)MySql 5.7添加用户、删除用户与授权
  8. [Kotlin Tutorials 19] Kotlin Flows, SharedFlow and StateFlow in Android
  9. Linkerd 2.10(Step by Step)—控制平面调试端点
  10. AI使用之技巧