?? 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[20],r[20]; ll BIT(ll x) { ll res=0; while(x){if(x&1LL) res++;x>>=1;} return res&1LL?-1LL:1LL;} void Ex_gcd(ll a,ll b,ll &d,ll &x,ll &y) { if(b==0){ d=a; x=1; y=0; 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=7; a=7; c1=0; for(int i=0;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-1-c1+M)/M;//以c1为起始量,M为等差的数列,在[L,R]中的个数。 } int main() { ll T,x,y,i,Case=0; scanf("%lld",&T); while(T--){ ans=0;tmp=0; scanf("%lld%lld%lld",&n,&x,&y); for(i=0;i<n;i++) scanf("%lld%lld",&m[i],&r[i]); for(i=0;i<1LL<<n;i++) ans+=BIT(i)*Ex_CRT(x,y,i); printf("Case #%lld: %lld\n",++Case,ans); } return 0; }