?? once wrote an autobiography, which mentioned something about himself. In his book, it said seven is his favorite number and he thinks that a number can be divisible by seven can bring him good luck. On the other hand, ?? abhors some other prime numbers and thinks a number x divided by pi which is one of these prime numbers with a given remainder ai will bring him bad luck. In this case, many of his lucky numbers are sullied because they can be divisible by 7 and also has a remainder of ai when it is divided by the prime number pi.
Now give you a pair of x and y, and N pairs of ai and pi, please find out how many numbers between x and y can bring ?? good luck.
InputOn the first line there is an integer T(T≤20) representing the number of test cases.
Each test case starts with three integers three intergers n, x, y(0<=n<=15,0<x<y<10181018) on a line where n is the number of pirmes.
Following on n lines each contains two integers pi, ai where pi is the pirme and ?? abhors the numbers have a remainder of ai when they are divided by pi.
It is guranteed that all the pi are distinct and pi!=7.
It is also guaranteed that p1*p2*…*pn<=10181018 and 0<ai<pi<=105105for every i∈(1…n).
OutputFor each test case, first output "Case #x: ",x=1,2,3...., then output the correct answer on a line.Sample Input
2
2 1 100
3 2
5 3
0 1 100
Sample Output
Case #1: 7
Case #2: 14
Hint
For Case 1: 7,21,42,49,70,84,91 are the seven numbers.
For Case2: 7,14,21,28,35,42,49,56,63,70,77,84,91,98 are the fourteen numbers.
题意:
求区间[X,Y]中模7为0,为满足n对关系:膜m[i]不为r[i],问这样的数字有多少。满足m[]为素数,且不为7。
思路:
- 容斥定理,保证了结果中不多算,不少算,不重复算。
- 中国剩余定理,求出最小的x=c1满足线性同余方程组,则变成求以c1为起始量,M=∏m[]为等差的数列,在[L,R]中的个数,结合抽屉原理,这里是奇加偶减。
- 保险起见,全部是long long
- 这里其实是用的线性同余方程组求解的,如果用中国剩余定理,得用快速除法。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#define ll long long
using namespace std;
ll n,ans,tmp,m[],r[];
ll BIT(ll x) { ll res=; while(x){if(x&1LL) res++;x>>=;} return res&1LL?-1LL:1LL;}
void Ex_gcd(ll a,ll b,ll &d,ll &x,ll &y)
{
if(b==){ d=a; x=; y=; return ;};
Ex_gcd(b,a%b,d,y,x);y-=a/b*x;
}
ll Ex_CRT(ll L,ll R,ll N)
{
ll a,b,c,c1,c2,x,y,d,M=;
a=; c1=;
for(int i=;i<n;i++){
if(!(1LL<<i&N)) continue;// 状态
M*=m[i];
b=m[i];c2=r[i]; c=c2-c1;
Ex_gcd(a,b,d,x,y);
x=((c/d*x)%(b/d)+b/d)%(b/d);//最小正单元
c1=a*x+c1;a=a*b/d;
}
return (R-c1+M)/M - (L--c1+M)/M;//以c1为起始量,M为等差的数列,在[L,R]中的个数。
}
int main()
{
ll T,x,y,i,Case=; scanf("%lld",&T);
while(T--){
ans=;tmp=;
scanf("%lld%lld%lld",&n,&x,&y);
for(i=;i<n;i++)
scanf("%lld%lld",&m[i],&r[i]);
for(i=;i<1LL<<n;i++) ans+=BIT(i)*Ex_CRT(x,y,i);
printf("Case #%lld: %lld\n",++Case,ans);
} return ;
}