济南学习 Day 4 T1 pm
幸运数字(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。
1 /* 2 代码太长,copy from other's 3 容斥原理 4 对于1~x中,ans=x/3+x/5+x/7-x/15-x/21-x/35+x/105 5 注意高精度时应该先把该加的都加上,在进行减法,这样可以避免出现负数。 6 */ 7 #include<cstdio> 8 #include<iostream> 9 #include<cstring> 10 #define N 200 11 using namespace std; 12 char s[N];int a1[N],b1[N],c1[N]; 13 struct node 14 { 15 int a[N],len; 16 void clear() 17 { 18 memset(a,0,sizeof(a));len=0; 19 } 20 };node s1,s2,ans; 21 node jia(node x,node y) 22 { 23 node c;c.clear(); 24 memset(a1,0,sizeof(a1)); 25 memset(b1,0,sizeof(b1)); 26 memset(c1,0,sizeof(c1)); 27 for(int i=1;i<=x.len;i++)a1[i]=x.a[x.len-i+1]; 28 for(int i=1;i<=y.len;i++)b1[i]=y.a[y.len-i+1]; 29 int len=max(x.len,y.len); 30 for(int i=1;i<=len;i++) 31 { 32 c1[i]+=a1[i]+b1[i]; 33 c1[i+1]+=c1[i]/10; 34 c1[i]%=10; 35 } 36 if(c1[len+1])len++; 37 c.len=len; 38 for(int i=len;i>=1;i--)c.a[i]=c1[len-i+1]; 39 return c; 40 } 41 node jian(node x,node y) 42 { 43 node c;c.clear(); 44 memset(a1,0,sizeof(a1)); 45 memset(b1,0,sizeof(b1)); 46 memset(c1,0,sizeof(c1)); 47 for(int i=1;i<=x.len;i++)a1[i]=x.a[x.len-i+1]; 48 for(int i=1;i<=y.len;i++)b1[i]=y.a[y.len-i+1]; 49 int len=max(x.len,y.len); 50 for(int i=1;i<=len;i++) 51 { 52 if(a1[i]>=b1[i])c1[i]=a1[i]-b1[i]; 53 else 54 { 55 c1[i]=a1[i]+10-b1[i]; 56 a1[i+1]--; 57 } 58 } 59 int p=len; 60 while(c1[p]==0)p--; 61 for(int i=p;i>=1;i--)c.a[++c.len]=c1[i]; 62 return c; 63 } 64 node chu(node x,int b) 65 { 66 node c;c.clear(); 67 memset(a1,0,sizeof(a1)); 68 int xx=0; 69 for(int i=1;i<=x.len;i++) 70 { 71 a1[i]=(xx*10+x.a[i])/b; 72 xx=xx*10+x.a[i]-a1[i]*b; 73 } 74 int len=1; 75 while(!a1[len]&&len)len++; 76 for(int i=len;i<=x.len;i++) 77 c.a[++c.len]=a1[i]; 78 return c; 79 } 80 void init() 81 { 82 s1.a[s1.len]--; 83 for(int i=s1.len;i>=1;i--) 84 { 85 if(s1.a[i]>=0)break; 86 else 87 { 88 s1.a[i]+=10; 89 s1.a[i-1]--; 90 } 91 } 92 if(!s1.a[1]) 93 { 94 s1.len--; 95 for(int i=1;i<=s1.len;i++) 96 s1.a[i]=s1.a[i+1]; 97 } 98 } 99 int main() 100 { 101 //freopen("number.in","r",stdin); 102 //freopen("number.out","w",stdout); 103 cin>>s;s1.len=strlen(s); 104 for(int i=1;i<=s1.len;i++)s1.a[i]=s[i-1]-'0'; 105 cin>>s;s2.len=strlen(s); 106 for(int i=1;i<=s2.len;i++)s2.a[i]=s[i-1]-'0'; 107 init(); 108 ans=chu(s2,3); 109 ans=jia(ans,chu(s2,5)); 110 ans=jia(ans,chu(s2,7)); 111 ans=jia(ans,chu(s2,105)); 112 ans=jia(ans,chu(s1,15)); 113 ans=jia(ans,chu(s1,21)); 114 ans=jia(ans,chu(s1,35)); 115 ans=jian(ans,chu(s2,15)); 116 ans=jian(ans,chu(s2,21)); 117 ans=jian(ans,chu(s2,35)); 118 ans=jian(ans,chu(s1,3)); 119 ans=jian(ans,chu(s1,5)); 120 ans=jian(ans,chu(s1,7)); 121 ans=jian(ans,chu(s1,105)); 122 for(int i=1;i<=ans.len;i++) 123 printf("%d",ans.a[i]); 124 return 0; 125 }
思路:容斥原理ans=(r/3+r/5+r/7-r/15-r/35-r/21+r/105)-((l-1)/3+(l-1)/5+(l-1)/7-(l-1)/15-(l-1)/35-(l-1)/21+(l-1)/105)