# 【数论】hdu5768 Lucky7（中国剩余定理）

http://acm.hdu.edu.cn/showproblem.php?pid=5768

{\displaystyle (S):\quad \left\{{\begin{matrix}x\equiv a_{1}{\pmod {m_{1}}}\\x\equiv a_{2}{\pmod {m_{2}}}\\\vdots \qquad \qquad \qquad \\x\equiv a_{n}{\pmod {m_{n}}}\end{matrix}}\right.}

1. {\displaystyle M=m_{1}\times m_{2}\times \cdots \times m_{n}=\prod _{i=1}^{n}m_{i}}是整数m1m2, ... , mn的乘积，并设{\displaystyle M_{i}=M/m_{i},\;\;\forall i\in \{1,2,\cdots ,n\}}，即{\displaystyle M_{i}}是除了mi以外的n − 1个整数的乘积。
2. {\displaystyle t_{i}=M_{i}^{-1}}{\displaystyle M_{i}}{\displaystyle m_{i}}数论倒数{\displaystyle t_{i}M_{i}\equiv 1{\pmod {m_{i}}},\;\;\forall i\in \{1,2,\cdots ,n\}.}从假设可知，对任何，由于，所以 这说明存在整数使得
3. 方程组{\displaystyle (S)}的通解形式为：{\displaystyle x=a_{1}t_{1}M_{1}+a_{2}t_{2}M_{2}+\cdots +a_{n}t_{n}M_{n}+kM=kM+\sum _{i=1}^{n}a_{i}t_{i}M_{i},\quad k\in \mathbb {Z} .} 在模{\displaystyle M}的意义下，方程组{\displaystyle (S)}只有一个解：{\displaystyle x=\sum _{i=1}^{n}a_{i}t_{i}M_{i}.}

int a[4], m[4];

void extend_Euclid(int a, int b, int &x, int &y)
{
if(b == 0)
{
x = 1;
y = 0;
return;
}
extend_Euclid(b, a % b, x, y);
int tmp = x;
x = y;
y = tmp - (a / b) * y;
}

int CRT(int a[],int m[],int n)
{
int M = 1;
int ans = 0;
for(int i=1; i<=n; i++)
M *= m[i];
for(int i=1; i<=n; i++)
{
int x, y;
int Mi = M / m[i];
extend_Euclid(Mi, m[i], x, y);
ans = (ans + Mi * x * a[i]) % M;
}
if(ans < 0) ans += M;
return ans;
}  

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
using namespace std;
#define MAXN 20

typedef  long long LL;
const LL mod = 1e9+7;

LL a[MAXN],m[MAXN];
LL pri[MAXN],moe[MAXN];

void exgcd(LL a,LL b,LL &d,LL& x,LL& y) {
if(!b) {
d=a;
x=1;
y=0;
} else {
exgcd(b,a%b,d,y,x);
y-=x*(a/b);
}
}

LL mul(LL a,LL b,LL mod) {
a%=mod;
LL ret=0;
while(b) {
if(b&1)ret=(ret+a)%mod;
b>>=1;
a=(a+a)%mod;
}
return ret;
}

LL china(int n,LL* a,LL *m) {
LL M=1,d,y,x=0;
for(int i=0; i<n; ++i)M*=m[i];
for(int i=0; i<n; ++i) {
LL w=M/m[i];
exgcd(m[i],w,d,d,y);
x=(x+mul(mul(y,w,M),a[i],M))%M;
}
return (x+M)%M;
}

int main() {
//freopen("in.txt","r",stdin);
int kase=0,n,T;
scanf("%d",&T);
while(T--) {
LL l,r;
scanf("%d",&n);
cin>>l>>r;
for(int i=0; i<n; ++i)
cin>>pri[i]>>moe[i];
LL len=(1<<n);
LL ret=r/7-(l-1)/7;
//对给出的几组质数排列组合，排除所有多余项（容斥）
for(int i=1; i<len; ++i) {
int cnt=0;
LL cur=1;
for(int j=0; j<n; ++j) {
if(i&(1<<j)) {
m[cnt]=pri[j];
a[cnt]=moe[j];
cnt++;
cur*=pri[j];
}
}
m[cnt]=7;
a[cnt]=0;
cur*=7;
cnt++;
LL tmp=china(cnt,a,m);
LL sub=0;
int poi=0;
if(tmp>=l&&tmp<=r) {
LL cha=r-tmp;
sub=cha/cur+1;//从tmp开始到r为止,需要排出的数字个数
}

else if(tmp<l) {
LL cha=l-tmp;
tmp+=(cha/cur)*cur;//如果tmp小于l,则使tmp>=l
if(tmp<l)tmp+=cur;
if(tmp>=l&&tmp<=r) {
cha=r-tmp;
sub=cha/cur+1;
}
}

//奇数加 偶数减(容斥)
if(cnt&1)ret+=sub;
else ret-=sub;
}
printf("Case #%d: %I64d\n",++kase,ret);
}
return 0;
}