幸运数字
题目描述:
LYK 最近运气很差,例如在 NOIP 初赛中仅仅考了 90 分,刚刚卡进复赛,于是它决定使用一些方法来增加自己的运气值。
它觉得,通过收集幸运数字可以快速的增加它的 RP 值。
它给幸运数字下了一个定义:如果一个数 x 能被 3 整除或被 5 整除或被 7 整除,则这个数为幸运数字。
于是它想让你帮帮它在 L~R 中存在多少幸运数字。
输入格式:
第一行两个数 L,R。
输出格式:
一个数表示答案。
输入样例
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。
思路:
容斥原理
设num(n,i)表示1~n中是i的倍数
则求1~n中3或5或7的倍数为
num(n,3)+num(n,5)+num(n,7)-num(n,3*5)-num(n,3*7)-num(5*7)+num(n,3*5*7)
这样求出1~r的减去1~l-1的即可
高精度!!!
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=1010;
int len,a[maxn],b[maxn],t[maxn],ans[maxn];
int sa[maxn],sb[maxn],c[2]={1,1};
char s1[maxn],s2[maxn];
void jian2(int *a,int *b)
{
memset(sa,0,sizeof(sa));
memset(sb,0,sizeof(sb));
sa[0]=a[0];
for(int i=1;i<=a[0];i++)
sa[i]=a[a[0]-i+1];
for(int i=1;i<=b[0];i++)
sb[i]=b[b[0]-i+1];
int len=1;
while(len<=sa[0])
{
sa[len]=sa[len]-sb[len];
if(sa[len]<0)
{
sa[len]=sa[len]+10;
sa[len+1]--;
}
len++;
}
while(sa[0]>1&&!sa[a[0]])
sa[0]--;a[0]=sa[0];
for(int i=1;i<=sa[0];i++)
a[i]=sa[sa[0]-i+1];
}
void div(int *r,int *a,int x)
{
int s=0;r[0]=a[0];
for(int i=1;i<=a[0];i++)
{
s=s*10+a[i];
r[i]=s/x;
s=s%x;
}
}
void add(int *a,int *b)
{
memset(sa,0,sizeof(sa));
memset(sb,0,sizeof(sb));
int len1=a[0],len2=b[0],len=1;
for(int i=1;i<=len2;i++)
sb[i]=b[len2-i+1];
while(len<=len1||len<=len2)
{
sa[len]+=a[len]+sb[len];
sa[len+1]=sa[len]/10;
sa[len]=sa[len]%10;
len++;
}
while(len>1&&!sa[len])
len--;sa[0]=len;
for(int i=0;i<=sa[0];i++) a[i]=sa[i];
}
void jian(int *a,int *b)
{
memset(sb,0,sizeof(sb));
for(int i=1;i<=b[0];i++)
sb[i]=b[b[0]-i+1];
int len=1;
while(len<=a[0])
{
a[len]=a[len]-sb[len];
if(a[len]<0)
{
a[len]=a[len]+10;
a[len+1]--;
}
len++;
}
while(a[0]>1&&!a[a[0]])
a[0]--;
}
int main()
{
freopen("number.in","r",stdin);
freopen("number.out","w",stdout);
cin>>s1>>s2;
int l1=strlen(s1),l2=strlen(s2);
a[0]=l1,b[0]=l2;
for(int i=1;i<=l1;i++) a[i]=s1[i-1]-'0';
for(int i=1;i<=l2;i++) b[i]=s2[i-1]-'0';
jian2(a,c);
div(t,b,3);add(ans,t);
div(t,b,5);add(ans,t);
div(t,b,7);add(ans,t);
div(t,a,3*5);add(ans,t);
div(t,a,3*7);add(ans,t);
div(t,a,5*7);add(ans,t);
div(t,b,3*5*7);add(ans,t);
div(t,b,3*5);jian(ans,t);
div(t,b,3*7);jian(ans,t);
div(t,b,5*7);jian(ans,t);
div(t,a,3);jian(ans,t);
div(t,a,5);jian(ans,t);
div(t,a,7);jian(ans,t);
div(t,a,3*5*7);jian(ans,t);
for(int i=ans[0];i>=1;i--)
cout<<ans[i];
fclose(stdin);fclose(stdout);
return 0;
}