51nod 1742 开心的小Q (容斥,分块)
来源:互联网 发布:按键精灵源码 编辑:程序博客网 时间:2024/06/05 17:28
输入数据包括2个数:a, b,中间用空格分隔。(1≤a≤b≤10^9)
输出a~b里每个数字的有趣约数个数之和。
1 10
4
题意:汉语题意就不在描述了。
思路:先求1到b,在求出1到a-1,然后做差。
任意一个完全平方数的倍数如果小于b,那么这个完全平方数的贡献就会加一次。那么这个完全平方数x的总贡献为b/x+b/(x*2)+b/(x*3)+b/x*4+....直到x的倍数大于b为止(这个地方要用分块会快一点)。所有完全平方数的贡献之和就是答案,但是有一点,36是完全平方数,4,9也是完全平方数,那么在计算4和9的倍数的时候,36被算了两次,那么这样有些数字被多次计算,所以要用容斥定理解决这个问题。
首先将所有小于b的完全平方数求出来,
4,9,16,25,36,49,64,81,100,121,144,169,196.......然后
1, 1 , 1, 1, 1, 1,1, 1, 1, 1, 1, 1, 1......这些数字是表示应该加上(这个完全平方数的贡献)的倍数。
计算完4以后,那么4的所有的(完全平方数)倍数,全部多算了1个,那么时4的(完全平方数)倍数所要计算的次数全部减一,减完后计算次数如下:
4,9, 16, 25, 36, 49, 64,81,100,121,144,169,196......
1, 1 , 1-1, 1, 1-1, 1,1-1, 1 ,1-1, 1 , 1-1, 1 , 1-1......
然后计算9,那么9的所有(完全平方数)倍数全部减去9算的次数
4,9, 16, 25, 36, 49, 64,81,100,121,144,169,196........
1, 1 , 0, 1, 0-1, 1, 0,1-1, 0, 1 ,0-1, 1 , 0.......
然后16为0就不用算了,然后算25的
4,9, 16, 25, 36, 49, 64,81,100,121,144,169,196........
1, 1 , 0, 1, -1, 1, 0, 0 , 0-1, 1 ,-1, 1 , 0.......
然后算36,36的倍数是-1,(这是因为4,和9都算了36,所以多算了一遍,所以要减去36的贡献的一倍)
然后就这样一直算下去,算完所有的完全平方数的贡献即可。
y+L*x<=b/(b/y);用二分的范围无法确定,那么就用倍增思想解决这个问题,找到的最大的L值加上1再乘以(b/y)就是这一块的贡献了。
代码:
#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<queue>#include<string>#include<algorithm>#define inf 0x3f3f3f3f#define LL long longusing namespace std;LL F(int &i,int y,int x)//这里的i是引用的{ int l=0,r=1,mid; int xx=x/(x/i); while(i+r*y<=xx)//倍增思想 { l=r; r*=2; } while(l<r) { mid=(l+r+1)/2; if(i+mid*y<=xx) l=mid; else r=mid-1; } i=i+l*y;//找到最大的符合条件的l值 return (LL)x/i*(l+1);}LL love(int y,int x){ LL sum=0LL; for(int i=y;i<=x;i+=y) sum+=F(i,y,x); return sum;}int p[100000];LL slove(int x){ memset(p,0,sizeof(p)); int lx=0; for(int i=2;i*i<=x;i++) { p[i]=1;//存该数字要计算的贡献的倍数 lx=i;//存最大的i } LL sum=0; for(int i=2;i<=lx;i++) { if(!p[i]) continue; sum+=p[i]*love(i*i,x); for(int j=i*2;j<=lx;j+=i) p[j]-=p[i];//更新倍数 } return sum;}int main(){ int a,b; scanf("%d%d",&a,&b); printf("%I64d\n",slove(b)-slove(a-1));}
- 51nod 1742 开心的小Q (容斥,分块)
- 51Nod-1742-开心的小Q
- 51nod 1742 开心的小Q
- 51nod 欢乐手速场C 开心的小Q
- 51nod 1742 开心的小Q(莫比乌斯函数)
- 51nod 1778 小Q的集合
- 51nod 1471 小S的兴趣 (分块)
- 51nod 1471 小S的兴趣 分块
- 51nod 1643 小Q的家庭作业
- 51nod 1284【容斥】
- [线性筛 质因数分解] 51Nod 1643 小Q的家庭作业
- [方差+lucas定理] 51nod 算法马拉松25 D. 小Q的集合
- 51nod 1806 wangyurzee的树(purfer,容斥原理)
- 51nod 1806 wangyurzee的树[purfer][容斥]
- 51nod 1284 容斥定理
- 51Nod - 1407 容斥原理 + dp
- 51nod 1678 容斥原理
- 【容斥】51Nod 1829 函数
- 4-10 阶乘计算升级版
- leetcode 502. IPO
- Swift 【为图片的加载提供便利构造方法】
- java随笔
- 课后作业之几何图形
- 51nod 1742 开心的小Q (容斥,分块)
- MapReduce从分片输出到Map
- HDU 1556 Color the ball
- |Rect|[pygame] 中文文档
- 文章标题
- 4.6Feature分支
- zookeeper3.4.6分布式集群安装部署记录
- PTA 7-5 字符串循环左移
- C++:cin\cin.getline()\getline()的用法