题意:
小明认为能被7整除的数能给他带来好运,但是如果这些数存在x%pi=ai(1<=i<=n)的话,它反而会给小明带来坏运。
问[x,y]区间里有多少个数能给小明带来好运?
分析:
明显的容斥题,但在容斥过程中得算x%pi=ai(1<=i<=n)中的x,明显是中国剩余定理。那么在计算过程中,将能被7整除看成%7==0,具体思想看代码。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll m[20];
ll a[20];
bool vis[20];
void exgcd(ll a,ll b,ll &x,ll &y)
{
if(b==0)
{
x=1;
y=0;
return;
}
ll tx,ty;
exgcd(b,a%b,tx,ty);
ll tmp=tx;
x=ty;
y=tmp-(a/b)*ty;
}
ll quick_mu(ll a,ll b,ll mod){
ll ans=0;
while(b){
if(b&1ll){
ans=(ans+a)%mod;
}
b>>=1;
a=(a<<1)%mod;
}
return ans;
}
ll count(ll M,ll ans,ll x){
return (x-ans+M)/M; //可以理解为(x-(ans-M))/M;因为ans也要计算上。数论上经常采用这种计数方法。0
}
ll CRT(int n,ll l,ll r){
ll M=1ll;
ll ans=0;
for(int i=0;i<n;i++){
if(vis[i]){
M*=m[i];
}
}
for(int i=0;i<n;i++){
if(vis[i]){
ll x,y;
ll Mi=M/m[i];
exgcd(Mi,m[i],x,y);
x=(x+m[i])%m[i];
ans=(ans+quick_mu(quick_mu(Mi,x,M),a[i],M)+M)%M;
}
}
return count(M,ans,r)-count(M,ans,l-1);
}
int main(){
int T;
scanf("%d",&T);
for(int cs=1;cs<=T;cs++){
ll n,l,r;
scanf("%lld%lld%lld",&n,&l,&r);
for(int i=0;i<n;i++){
scanf("%lld%lld",&m[i],&a[i]);
}
m[n]=7,a[n]=0,vis[n]=1;
int up=1ll<<n;
ll ans=0;
for(int i=0;i<up;i++){ //这块记得从0开始。
ll tmp=1,cnt=0;
for(int j=0;j<n;j++){
if((i&(1ll<<j))) vis[j]=1,cnt^=1;
else vis[j]=0;
}
if(cnt) ans-=CRT(n+1,l,r);
else ans+=CRT(n+1,l,r);
}
printf("Case #%d: %lld\n",cs,ans);
}
return 0;
}