首页 > 代码库 > HDU 5768 Lucky7(CRT+容斥原理)

HDU 5768 Lucky7(CRT+容斥原理)

 

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

 

【题目大意】

  求出一个区间内7的倍数中,对于每个ai取模不等于bi的数的个数。

 

【题解】

  首先,对于x mod 7=0,和选取的一些x mod ai=bi,我们可以利用CRT解出最小的x值,那么这样子我们就可以对所有的aibi选取方式做容斥,得到x mod 7=0成立且所有x mod ai=bi不成立的x的个数。也就是答案。

 

【代码】

#include <cstdio>#include <algorithm>#include <cmath>using namespace std;typedef long long LL;LL a[20],b[20],l,r;int T,n,Cas=1,vis[20];LL pow(LL a,LL b,LL p){LL t=1;for(a%=p;b;b>>=1LL,a=a*a%p)if(b&1LL)t=t*a%p;return t;}LL Cal(LL r,LL l,LL m){return (r-l)/m;}LL CRT(LL*a,LL*b,int n){    LL ans=0,P=1;    for(int i=0;i<n;i++)if(vis[i])P*=a[i];      for(int i=0;i<n;i++)if(vis[i])ans=(ans+(P/a[i])*pow(P/a[i],a[i]-2,a[i])%P*b[i]%P)%P;    while(ans<0)ans+=P;    return Cal(r+P,ans,P)-Cal(l-1+P,ans,P);}int main(){    scanf("%d",&T);     a[0]=7;b[0]=0;vis[0]=1;    while(T--){        scanf("%d%lld%lld",&n,&l,&r);        for(int i=1;i<=n;i++)scanf("%d%d",a+i,b+i),vis[i]=0;        LL ans=0; int all=1<<n;        for(int i=0;i<all;i++){            int U=i,cnt=0;            for(int j=1;j<=n;j++)vis[j]=U&1,U>>=1,cnt+=vis[j];            cnt=cnt&1?-1:1;            ans+=1LL*cnt*CRT(a,b,n+1);        }printf("Case #%d: %lld\n",Cas++,ans);    }return 0;}

  

HDU 5768 Lucky7(CRT+容斥原理)