bzoj 3994 约数个数和 —— 反演+数论分块
2024-09-06 18:40:04
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3994
推导过程和这里一样:https://www.cnblogs.com/MashiroSky/p/6365020.html
不用取模但注意开 long long 。
代码如下:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
int const xn=5e4+;
int cnt,pri[xn];
ll f[xn],mu[xn];
bool vis[xn];
int rd()
{
int ret=,f=; char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=; ch=getchar();}
while(ch>=''&&ch<='')ret=ret*+ch-'',ch=getchar();
return f?ret:-ret;
}
void init()
{
int mx=5e4; mu[]=;
for(int i=;i<=mx;i++)
{
if(!vis[i])pri[++cnt]=i,mu[i]=-;
for(int j=;j<=cnt&&(ll)i*pri[j]<=mx;j++)
{
vis[i*pri[j]]=;
if(i%pri[j])mu[i*pri[j]]=-mu[i];
else break;
}
}
for(int i=;i<=mx;i++)mu[i]+=mu[i-];
for(int n=;n<=mx;n++)
for(int i=,j;i<=n;i=j+)
{
j=n/(n/i);
f[n]+=(ll)(n/i)*(j-i+);//
}
}
int main()
{
int T=rd(); init();
while(T--)
{
int n=rd(),m=rd(); int mn=min(n,m); ll ans=;//
for(int i=,j;i<=mn;i=j+)
{
j=min(n/(n/i),m/(m/i));
ans+=(mu[j]-mu[i-])*f[n/i]*f[m/i];
}
printf("%lld\n",ans);
}
return ;
}
最新文章
- ContextFlyout 在10586或10240的使用
- Intellij IDEA 常用快捷键
- windows下CMake使用图文手册 Part 4
- 聚合数据董铭彦:小程序开发的兴起将带火API数据交易
- 安卓开发_浅谈SubMenu(子菜单)
- [MySQL] - MySQL的Grant命令
- Laravel Repository 模式
- [POJ] 2239 Selecting Courses(二分图最大匹配)
- Threejs 它可以在建立其内部房间效果可见
- storyboard页面跳转传值
- 安卓AsyncTack详解
- TensorFlow从1到2(一)续讲从锅炉工到AI专家
- wpf 的各个template
- nlp底层技术列举
- Linux配置SSH免登录
- 爬虫系列3:scrapy技术进阶(xpath、rules、shell等)
- Bootstrap 代码
- 程序员面试50题—sizeof的用法(6)
- WebApplication与WebSite区别
- EsayUI + MVC + ADO.NET(仓储基类)