无知者无畏。|

Oier_szc

园龄:2年1个月粉丝:4关注:4

2024-02-09 00:30阅读: 12评论: 0推荐: 0

洛谷P3327 笔记

传送门

题意

d(x)x 的因数个数,然后给定 T 组询问,对于每一个询问给定 nm ,求 i=1nj=1m

1T,n,m5×104

正文

重要结论

这题的难点之一就是第一步的转换。

需要用到一个重要结论:d(ij)=x|iy|j[gcd(i,j)=1]

来自这位dalao的证明:

考虑从朴素的角度求出 d(x) ,一种可行的方法是枚举每种质因子的出现次数。

于是对于 s 的一种质因子 p ,设 cnts,p 表示 s 中有 cnts,pp ,则这种暴力的策略会枚举 pcntp 种不同的大小 p,p2...pcnts,p 。于是得出结论:对于 psp 会被枚举 cntp 次。

那么对于 s=ij ,只要让质因子被枚举 cnti,p+cntj,p 次即可。那么一种可行的策略就是枚举所有满足 x|i,y|j,gcd(x,y)=1 的数对,这样的话当 px 时,py ,此时 p 被枚举 cntx,p 次。反之亦然。于是 p 共被枚举 cnti,p+cntj,p 次,满足条件。所以结论成立。

推柿子

于是原式变为 i=1nj=1mx|iy|j[gcd(i,j)=1]

这个 [gcd(i,j)=1] 非常的臭,用莫比乌斯函数把它撅了。

于是转换成:i=1nj=1mx|iy|jd|gcd(i,j)μ(d)

枚举 x,y。就有 x=1ny=1md|gcd(i,j)μ(d)nxmy

进一步地,枚举 d。于是 d=1min(n,m)μ(d)x=1ndndxy=1mdmdy

这个时候思路已经逐渐出来了。后面的 x=1ndndxy=1mdmdy 是标准的整除分块模板。设 g(i)=i=1nni ,原式又变成了 d=1min(n,m)μ(d)g(nd)g(md)

由于 μ(d) 珂以线性筛预处理,于是就出现了整除分块套整除分块,非常鬼畜!但正解就是这样。

code

//writer:Oier_szc
#include <bits/stdc++.h>
#define TS cerr<<"I AK IOI"<<endl;
#define int long long
using namespace std;
const int N=5e4+5,INF=2e9,mod=1e9+7;
int t;
int n,m;
int primes[N],st[N],len=0;
int f[N],g[N];
void init()
{
f[1]=1;
for(int i=2;i<=5e4;++i)
{
if(!st[i]) primes[++len]=i,f[i]=-1;
for(int j=1;j<=len&&primes[j]<=5e4/i;++j)
{
st[i*primes[j]]=true;
if(i%primes[j]==0)
{
f[i*primes[j]]=0;
break;
}
else f[i*primes[j]]=-f[i];
}
}
for(int i=1;i<=5e4;++i)
{
f[i]+=f[i-1];
for(int l=1,r;l<=i;l=r+1)
{
r=i/(i/l);
g[i]+=(r-l+1)*(i/l);
}
}
}
signed main()
{
init();
scanf("%lld",&t);
while(t--)
{
scanf("%lld%lld",&n,&m);
int R=min(n,m),ans=0;
for(int l=1,r;l<=R;l=r+1)
{
r=min(n/(n/l),m/(m/l));
ans+=(f[r]-f[l-1])*g[n/l]*g[m/l];
}
printf("%lld\n",ans);
}
return 0;
}

本文作者:StevenZC

本文链接:https://www.cnblogs.com/StevenZC/p/18012280

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   Oier_szc  阅读(12)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起