给你一个区间,问你在这个区间内 不满足模m[i]等于a[i]的 并且能被7整除的个数有几个
这题因为n只有15 所以直接状态压缩一下,把状态容斥一下就好了。注意乘法要用快速乘法,要不然会爆longlong
AC代码:
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<iostream>
using namespace std;
typedef __int64 ll;
const int maxn=16;
ll m[maxn],a[maxn],s[maxn];
ll l,r;
ll gao(ll x,ll y,ll M){
return (x-y)/M;
}
void extend_Euclid(ll a, ll b, ll &x, ll &y)
{
if(b == 0)
{
x = 1;
y = 0;
return;
}
extend_Euclid(b, a % b, x, y);
ll tmp = x;
x = y;
y = tmp - (a / b) * y;
}
ll Mult(ll a,ll k,ll M){
ll res=0;
while(k){
if(k & 1)
res=(res+a)%M;
k>>=1;
a=(a<<1)%M;
}
return res;
}
ll China(int n){
ll M=1,res,ans=0;
for(int i=0;i<=n;i++)
if(s[i]) M*=m[i];
for(int i=0;i<=n;i++) if(s[i]){
ll x,y;
ll Mi=M/m[i];
extend_Euclid(Mi,m[i],x,y);
x=(x%m[i]+m[i])%m[i];//x取最小整数,要不然会t
ans=((ans+Mult(a[i]*Mi,x,M))%M +M)%M;
}
res=gao(r+M,ans,M)-gao(l-1+M,ans,M);
return res;
}
int main()
{
int n,t;
ll ans;
cin>>t;
for(int icas=1;icas<=t;icas++){
cin>>n>>l>>r;
ans=0;
memset(s,0,sizeof(s));
for(int i=0;i<n;i++)
scanf("%d%d",&m[i],&a[i]);
m[n]=7;a[n]=0;s[n]=1;
for(int stu=0;stu<(1<<n);stu++){
int k=0;
for(int i=0;i<n;i++){
if((1<<i) & stu)
{s[i]=1;k++;}
else s[i]=0;
}
k=k&1?-1:1;
ans+=China(n)*k* 1ll;
}
printf("Case #%d: ",icas);
cout<<ans<<endl;
}
}
/*
2
2 1 100
3 2
5 3
0 1 100
*/