济南学习 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)

原文地址:https://www.cnblogs.com/suishiguang/p/6040352.html