HDU 5768 Lucky7

题目:Lucky7

链接:http://acm.hdu.edu.cn/showproblem.php?pid=5768

题意:给你两个数组a[],b[],当某一个数x能整除7,且对所有的i,x%a[i]!=b[i],则称这个数是幸运数,问区间l、r中有多少幸运数。

思路:

  线性同余(中国剩余定理可解)+容斥。

  坑点:使用中国剩余定理的计算过程中,有可能会爆longlong,需要自己写个快速乘取余。比赛的时候脑袋有点晕,wa到死就是没看到这点,好坑。

  大概思路就是找出区间内所有7的倍数,减去那些取余a[i]会等于b[i]的情况。 基本上就是模板题了,没什么好讲的。

AC代码:

  1 #include<stdio.h>
  2 typedef long long LL;
  3 void exGcd(LL a,LL b,LL &d,LL &x,LL &y)
  4 {
  5   if(b==0)
  6   {
  7     d=a;
  8     x=1;
  9     y=0;
 10   }
 11   else
 12   {
 13     exGcd(b,a%b,d,x,y);
 14     LL t=x;
 15     x=y;
 16     y=t-a/b*y;
 17   }
 18 }
 19 
 20 LL mul(LL a,LL b,LL mod)
 21 {
 22   LL ret=0;
 23   while(b)
 24   {
 25     if(b&1) ret=(ret+a)%mod;
 26     a=(a+a)%mod;
 27     b>>=1;
 28   }
 29   return ret;
 30 }
 31 
 32 LL fun1(LL aa,LL bb,LL &pp)
 33 {
 34   LL m=aa*7;
 35   LL a[2],b[2];
 36   a[0]=aa;
 37   b[0]=bb;
 38   a[1]=7;
 39   b[1]=0;
 40 
 41   pp=0;
 42   for(LL i=0;i<2;i++)
 43   {
 44     LL mi=m/a[i],d,p,q;
 45     exGcd(mi,a[i],d,p,q);
 46     p=(p%a[i]+a[i])%a[i];
 47     pp=(pp+mul(mul(mi,p,m),b[i],m))%m;
 48   }
 49   pp%=m;
 50   return m;
 51 }
 52 LL a[20],b[20];
 53 LL fun(LL *st,LL so,LL &pp)
 54 {
 55   LL m=1;
 56   for(LL i=0;i<so;i++)
 57   {
 58     m*=a[st[i]];
 59   }
 60   pp=0;
 61   for(LL i=0;i<so;i++)
 62   {
 63     LL mi=m/a[st[i]],d,p,q;
 64     exGcd(mi,a[st[i]],d,p,q);
 65     p=(p%a[st[i]]+a[st[i]])%a[st[i]];
 66     pp=(pp+mul(mul(mi,p,m),b[st[i]],m))%m;
 67   }
 68   pp%=m;
 69   return m;
 70 }
 71 LL l,r;
 72 LL n;
 73 LL fin(LL a,LL b,LL l,LL r)
 74 {
 75   l-=b;
 76   r-=b;
 77   l+=a;
 78   r+=a;
 79   return r/a-(l-1)/a;
 80 
 81 }
 82 void dfs(LL num,LL ceng,LL j,LL *st,LL so,LL &all)
 83 {
 84   if(ceng==num)
 85   {
 86     LL p;
 87     LL m=fun(st,so,p);
 88     LL pp;
 89     LL mm=fun1(m,p,pp);
 90 
 91 
 92     LL tmp=fin(mm,pp,l,r);
 93 
 94     all+=tmp;
 95     //printf("pp=%I64d mm=%I64d all=%I64d\n",pp,mm,all);
 96     return ;
 97   }
 98   for(LL i=j;i<n;i++)
 99   {
100     st[so++]=i;
101     dfs(num,ceng+1,i+1,st,so,all);
102     so--;
103   }
104 }
105 LL st[1000],so;
106 int main()
107 {
108   LL t,cas=1;
109   scanf("%I64d",&t);
110   while(t--)
111   {
112     scanf("%I64d%I64d%I64d",&n,&l,&r);
113     for(LL i=0;i<n;i++)
114     {
115       scanf("%I64d%I64d",&a[i],&b[i]);
116     }
117     LL sum=0;
118     for(LL i=1;i<=n;i++)
119     {
120       so=0;
121       LL all=0;
122       //printf("==========%d\n",i);
123       dfs(i,0,0,st,so,all);
124       if(i%2==1)
125       {
126         sum+=all;
127       }
128       else sum-=all;
129     }
130     printf("Case #%I64d: %I64d\n",cas++,r/7-(l-1)/7-sum);
131   }
132   return 0;
133 }

 

posted @ 2016-07-28 19:07  hchlqlz  阅读(436)  评论(0编辑  收藏  举报