BZOJ2301: [HAOI2011]Problem b 莫比乌斯反演+容斥原理
来源:互联网 发布:java attribute用法 编辑:程序博客网 时间:2024/05/01 20:14
第一次写莫比乌斯反演,感觉这个东西真的神奇,之前就因为使用莫比乌斯函数做容斥原理就久闻莫比乌斯反演大名,今日终于大概搞懂了莫比乌斯反演,其实说白了就是两个函数满足如下条件时
有如下反演存在
这个式子就叫做莫比乌斯反演,其中u为莫比乌斯函数。
这只是一种最常用的表示的方法,还有一种表示方法在信息学竞赛中更为常用,其形式如下
这道题用到的即为这种表示方法,让我们来看看莫比乌斯反演是如何优化这道题的。
首先我们看到一个询问是两段区间,那么我们就用容斥原理将这个询问拆成四个来做,首先我们看得出求出两个数的gcd为k并不好搞,那么我们就将n,m同除以一个k,这样找区间内互质的数的个数即可,我们设一个函数f(i)表示两个数gcd为i的答案的个数,这个东西显然不太好搞,但是如果有一个函数F(i)表示i|gcd(x,y)的数对的总数的话就比较无脑了,这个值我们可以很容易的推出来应该等于(n/i)*(m/i)(下取整),那么根据刚才的第二个反演公式则有如下表达式
由于我们要找的是互质的数对的个数,所以这里的i取1,将一代入式子以后我们发现变成了一个求和的问题,但是每次都暴力求肯定是不行的,所以我们搞一些玄学的优化,我们发现(n/d)最多只有2*根号n个取值,m也同理,那么(n/d)*(m/d)也就只有根号n加根号m个取值(注意不是乘),那么我们枚举这个取值再乘上这个取值的个数即可,这个个数就是对u进行前缀和的处理,得到边界的方法也极其的简单,这样的话查询时间复杂度就被我们优化成了根号n的级别,这道题就可以水过了。
#include<cstdio>#include<cstdlib>#include<cmath>#include<ctime>#include<cstring>#include<string>#include<iostream>#include<iomanip>#include<algorithm>using namespace std;int u[100100];int zhi[100100];bool pd[100100];int top=0;void shai(){ u[1]=1; for(int i=2;i<=100000;i++) { if(!pd[i]) zhi[++top]=i,u[i]=-1; for(int j=1;j<=top && i*zhi[j]<=100000;j++) { pd[i*zhi[j]]=true; if(i%zhi[j]==0) break; u[i*zhi[j]]=-u[i]; } } for(int i=1;i<=100000;i++) u[i]+=u[i-1];}long long jisuan(int n,int m,int k){ n/=k; m/=k; int last; long long re=0; for(int i=1;i<=n && i<=m;i=last+1) { last=min(n/(n/i),m/(m/i)); re+=(long long)(n/i)*(m/i)*(u[last]-u[i-1]); } return re;}int main(){ int n; scanf("%d",&n); shai(); for(int i=1;i<=n;i++) { int a,b,c,d,k; scanf("%d%d%d%d%d",&a,&b,&c,&d,&k); printf("%lld\n",jisuan(b,d,k)+jisuan(a-1,c-1,k)-jisuan(a-1,d,k)-jisuan(b,c-1,k)); }}
0 0
- BZOJ2301: [HAOI2011]Problem b 莫比乌斯反演+容斥原理
- [莫比乌斯反演+容斥+分块求和] BZOJ2301: [HAOI2011]Problem b
- 【容斥+莫比乌斯反演】BZOJ2301 [HAOI2011]Problem b
- bzoj2301: [HAOI2011]Problem b 莫比乌斯反演
- BZOJ2301 [HAOI2011]Problem b(莫比乌斯反演)
- BZOJ2301: [HAOI2011]Problem b 莫比乌斯反演
- 【bzoj2301】[HAOI2011]Problem b 莫比乌斯反演
- Bzoj2301: [HAOI2011]Problem b:莫比乌斯反演
- [BZOJ2301][HAOI2011]Problem b(莫比乌斯反演)
- Bzoj2301 [HAOI2011]Problem b 莫比乌斯反演
- 【BZOJ2301】【HAOI2011】Problem b 莫比乌斯反演
- [BZOJ2301][HAOI2011]Problem b(莫比乌斯反演)
- bzoj2301 [HAOI2011]Problem b(莫比乌斯反演)
- 【BZOJ2301】【HAOI2011】Problem B(莫比乌斯反演)
- [BZOJ2301][HAOI2011]Problem b(莫比乌斯反演)
- bzoj2301 [HAOI2011]Problem b(求gcd==k的个数)(莫比乌斯反演+容斥原理)
- BZOJ 2301 HAOI2011 Problem b 容斥原理+莫比乌斯反演
- BZOJ 2301: [HAOI2011]Problem b(莫比乌斯反演 + 容斥原理 + 分块优化)
- Eigen教程1 - 基础
- 【UOJ】#241. 【UR #16】破坏发射台
- 【HDU 3038 How Many Answers Are Wrong】+ 并查集
- LeetCode 412. Fizz Buzz(Java)
- 深入理解JVM—JVM内存模型
- BZOJ2301: [HAOI2011]Problem b 莫比乌斯反演+容斥原理
- poj 3259 Wormholes
- N个有序整数数列已放在一维数组中,利用二分查找法查找整数m在数组中的位置,若找到,则输出其下标值;反之,则输出 “Not be found”
- Elasticsearch创建索引和映射结构详解
- 排序算法1——冒泡排序
- 基础练习 字符串对比
- 跨iframe通信方案
- 文件上传
- ElasticSearch什么是文档?索引一个文档