非整除序列
2015-08-11 21:18
141 查看
题意
定义S(N)为最小的不能整除N 的正整数,接下再计算S(S(N))、S(S(S(N)))直到得到数字2。定义strength(N)为上述过程得到的序列长度。如N=6 时得到的序列为6,4,3,2,strength(6)=4。给定两个正整数A,B,A < B,计算strength(A)+strength(A+1)+…+strength(B)。3≤A<B≤10173\le A < B\le 10^{17}
分析
每个数的序列第一个数是它自己,我们要知道的就是它第二个数是什么。我们可以发现,若一个数X,它序列的第二个数为y,则X 为Py−1P_{y-1} 的倍数,且X不为PyP_{y}的倍数。其中PiP_i为2~i的所有数的最小公倍数,对于一个数PiP_i,我们可以知道区间内它的倍数有多少个。并且计算发现,ii做到41左右就会大于最大值了。#include <cstdio> const int N = 45; typedef long long LL; int f ; LL l,r; LL calc(LL x) { if (x == 2) return 1; if (x <= N) { if (f[x]) return f[x]; for (int i = 2;i <= N;i ++) if (x % i != 0) return f[x] = calc(i) + 1; } for (int i = 2;i <= N;i ++) if (x % i != 0) return calc(i) + 1; } LL count(LL l,LL r,LL x) { return r / x - (l - 1) / x; } LL gcd(LL a,LL b) { if (b == 0) return a; return gcd(b,a % b); } int main() { scanf("%lld%lld",&l,&r); LL last = 1,cur = 1,ans = 0; for (LL i = 2;i <= N;i ++) { if (last > r) break; cur = cur * i / gcd(cur,i); ans += (calc(i) + 1) * (count(l,r,last) - count(l,r,cur)); last = cur; } printf("%lld\n",ans); }
相关文章推荐
- 2015/8/11/单例/MVC/Web Servlet/事务
- JDBC学习小结
- 软件测试的总结01
- Java常见问题3:周期之谜
- MySQL的分页
- C语言基础01
- OpenGL ES 画球
- ADAM4015应用笔记
- httpclient中使用HTTPS的方法
- hdoj2122Ice_cream’s world III
- 【屌丝程序的口才逆袭演讲稿50篇】第十三篇:爱迪生欺骗了我们!【张振华.Jack】
- leetcode Merge Two Sorted Lists
- HDOJ 1102 Constructing Roads 最小生成树 kruskal && Prim
- Zookeeper之观察机制(配置服务)
- POJ 3169 Layout (差分约束)
- HDU 2122 HDU Today(dijkstra+map)
- 黑马程序员——详细的类的声明和实现
- Hdu 3068 Manacher算法求最长回文串长度
- 更新UI方式
- IOS 本地通知和远程通知