解(1<<(n+1))-1个同余方程组,然后容斥。作为中国剩余定理的模版。另外数据范围刚好超出long long,用了__int128。
#include <iostream>
#include <stdio.h>
#include <cmath>
#include <algorithm>
#include <string>
#include <string.h>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <sstream>
using namespace std;
#define ll __int128
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 CRT(ll a[],ll m[],ll n){
ll M = 1;
ll ans = 0;
for(int i=0; i<n; i++)
M *= m[i];
for(int i=0; i<n; i++){
ll x, y;
ll 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;
}
ll p[20];
ll a[20];
ll read(){
long long res = 0;
cin>>res;
return res;
}
int main(){
int t;
cin>>t;
int cas = 0;
while(t--){
cas++;
ll n,l,r;
n = read();
l = read();
r = read();
for(int i=0;i<n;i++){
p[i] = read();
a[i] = read();
}
int End = 1<<n;
ll ans = 0;
for(int k=0;k<End;k++){
int bc = __builtin_popcount(k);
ll mm[20];
ll aa[20];
int sz = 0;
ll lcm = 7;
for(int i=0;i<n;i++){
if(k&(1<<i)){
mm[sz] = p[i];
aa[sz] = a[i];
lcm *= p[i];
sz++;
}
}
mm[sz] = 7;
aa[sz] = 0;
sz++;
ll crt = CRT(aa,mm,sz);
ll la = l/lcm;
ll ra = r/lcm;
ll tmp = ra - la;
if((l%lcm)<=crt && (r%lcm)>=crt){
tmp++;
}
if((l%lcm)>crt && (r%lcm)<crt){
tmp--;
}
if(bc&1){
ans -= tmp;
}else{
ans += tmp;
}
}
printf("Case #%d: ",cas);
long long ANS = ans;
cout<<ANS<<endl;
}
return 0;
}