博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BZOJ2301: [HAOI2011]Problem b 莫比乌斯反演
阅读量:5152 次
发布时间:2019-06-13

本文共 1223 字,大约阅读时间需要 4 分钟。

分析:对于给出的n个询问,每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d,且gcd(x,y) = k,gcd(x,y)函数为x和y的最大公约数。

    然后对于求这样单个的gcd(x,y)=k的,我们通常采用莫比乌斯反演

但是,时间复杂度是O(n*(n/k))的,当复杂度很坏的时候,当k=1时,退化到O(n^2),超时

然后进行分块优化,时间复杂度是O(n*sqrt(n))

#include
#include
#include
#include
#include
#include
#include
using namespace std;typedef long long LL;const int N=5e4+5;const int INF=0x3f3f3f3f;bool vis[N];int prime[N],mu[N],cnt;void getmu(){ mu[1] = 1; for(int i=2; i<=N-5; i++) { if(!vis[i]) { prime[++cnt] = i; mu[i] = -1; } for(int j=1; j<=cnt&&i*prime[j]<=N-5; j++) { vis[i*prime[j]] = 1; if(i%prime[j]) mu[i*prime[j]] = -mu[i]; else { mu[i*prime[j]] = 0; break; } } }}LL solve(int n,int m,int k){ n/=k,m/=k; int l=min(n,m); LL ans=0; for(int i=1,j;i<=l;i=j+1){ j=min(n/(n/i),m/(m/i)); ans+=1ll*(mu[j]-mu[i-1])*(n/i)*(m/i); } return ans;}int main(){ getmu(); for(int i=1;i<=N-5;++i)mu[i]+=mu[i-1]; int T; scanf("%d",&T); while(T--){ int a,b,c,d,k; scanf("%d%d%d%d%d",&a,&b,&c,&d,&k); printf("%lld\n",solve(b,d,k)-solve(b,c-1,k)-solve(a-1,d,k)+solve(a-1,c-1,k)); } return 0;}
View Code

 

转载于:https://www.cnblogs.com/shuguangzw/p/5440507.html

你可能感兴趣的文章
虚拟机长时间不关造成的问题
查看>>
校门外的树2 contest 树状数组练习 T4
查看>>
面试整理:Python基础
查看>>
Python核心编程——多线程threading和队列
查看>>
Program exited with code **** 相关解释
查看>>
装服务器,测试数据库,简单的maven命令
查看>>
升级Firefox8后watir-webdriver出现错误“unable to obtain stable firefox connection in 60 seconds”...
查看>>
植物大战僵尸中文年度版
查看>>
26、linux 几个C函数,nanosleep,lstat,unlink
查看>>
001.RAID简介
查看>>
投标项目的脚本练习2
查看>>
第五次实验
查看>>
201521123107 《Java程序设计》第9周学习总结
查看>>
runtime的基本应用
查看>>
关于scrollTop的那些事
查看>>
Caroline--chochukmo
查看>>
算法导论笔记 第8章 线性时间排序
查看>>
利用jquery的contains实现搜索功能
查看>>
Xcode 6.2 beta 3 太难下载!下载了,不敢独享
查看>>
并发编程
查看>>