幸运数字(number)
Time Limit:1000ms Memory Limit:64MB
【题目描述】
LYK最近运气很差,例如在NOIP初赛中仅仅考了90分,刚刚卡进复赛,于是它决定使用一些方法来增加自己的运气值。它觉得,通过收集幸运数字可以快速的增加它的RP值。它给幸运数字下了一个定义:如果一个数x能被3整除或被5整除或被7整除,则这个数为幸运数字。于是它想让你帮帮它在L~R中存在多少幸运数字。
【输入格式】(number.in)
第一行两个数L,R。
【输出格式】(number.out)
一个数表示答案。
【输入样例】
10 15
【输出样例】
4
【数据范围】
对于50%的数据1<=L<=R<=10^5。
对于60%的数据1<=L<=R<=10^9。
对于80%的数据1<=L<=R<=10^18。
对于90%的数据1<=L<=R<=10^100。
对于另外10%的数据L=1,1<=R<=10^100。
对于100%的数据L,R没有前导0。
【题目分析】
从L到R中能被3 5 7整除的数字,那就算一下这个区间:3的倍数+5的倍数+7的倍数-15的倍数-35的倍数-21的倍数+105的倍数(容斥原理),要注意计算L之内的数的个数时,L不能算在内(跟 前缀和是同样的原理)
我们会发现后面还有两组数据的R<=10^100T_T ,高精,弃了。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; long long l,r; int main() { freopen("number.in","r",stdin); freopen("number.out","w",stdout); scanf("%I64d%I64d",&l,&r); l--; long long ans1=l/3+l/5+l/7-l/15-l/21-l/35+l/105; long long ans2=r/3+r/5+r/7-r/15-r/21-r/35+r/105; cout << ans2-ans1; fclose(stdin);fclose(stdout); return 0; }
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#include <cmath> #include <cstdio> #include <cstdlib> #include <iostream> #include <algorithm> #include <string> #include <cstring> using namespace std; char s1[1005],s2[1005]; int S1[1005],S2[1005],len1,len2,s[1005],S[1005],i; void pl(int *a,int *b) { for (int i=a[0]+1; i<=b[0]; i++) a[i]=0; for (int i=1; i<=b[0]; i++) a[i]+=b[i]; a[0]=max(a[0],b[0]); for (int i=1; i<a[0]; i++) if (a[i]>=10) {a[i+1]++; a[i]-=10;} if (a[a[0]]>=10) {a[a[0]+1]=1; a[a[0]]-=10; a[0]++;} } void mn(int *a,int *b) { for (int i=a[0]+1; i<=b[0]; i++) a[i]=0; for (int i=1; i<=b[0]; i++) a[i]-=b[i]; for (int i=1; i<a[0]; i++) if (a[i]<0) {a[i]+=10; a[i+1]--;} while (a[0]>1 && a[a[0]]==0) a[0]--; } void work(int *a,int b,int *c) { for (int i=1; i<=a[0]; i++) c[i]=a[i]; for (int i=a[0]; i>=1; i--) { c[i-1]+=c[i]%b*10; c[i]/=b; } c[0]=a[0]; while (c[0]>1 && c[c[0]]==0) c[0]--; } int main() { freopen("number.in","r",stdin); freopen("number.out","w",stdout); scanf("%s",s1); scanf("%s",s2); len1=strlen(s1); len2=strlen(s2); for (i=1; i<=len1; i++) S1[len1-i+1]=s1[i-1]-'0'; S1[0]=len1; for (i=1; i<=len2; i++) S2[len2-i+1]=s2[i-1]-'0'; S2[0]=len2; work(S2,3,s); work(S2,5,S); pl(s,S); work(S2,7,S); pl(s,S); work(S2,15,S); mn(s,S); work(S2,21,S); mn(s,S); work(S2,35,S); mn(s,S); work(S2,105,S); pl(s,S); S[0]=1; S[1]=1; mn(S1,S); work(S1,15,S); pl(s,S); work(S1,21,S); pl(s,S); work(S1,35,S); pl(s,S); work(S1,3,S); mn(s,S); work(S1,5,S); mn(s,S); work(S1,7,S); mn(s,S); work(S1,105,S); mn(s,S); for (i=s[0]; i>=1; i--) cout<<s[i]; return 0; }