题目描述 Description
Skytree神犇最近在研究中国博大精深的数学。
这时,Sci蒟蒻前来拜访,于是Skytree给Sci蒟蒻出了一道数学题:
给定n个质数,以及k模这些质数的余数。问:在闭区间[a,b]中,有多少个k?最小的k是多少?
Sci蒟蒻数学能力差了Skytree三条街,所以他只好寻求计算机的帮助。他发邮件给同为oier的你,你能帮他解决这个问题吗?
输入描述 Input Description
输入第一行为三个正整数n、a、b。
第2到n+1行,每行有两个整数,分别代表第n个质数和k模第n个质数的余数。
输出描述 Output Description
输出为两个整数,代表闭区间[a,b]中k的个数和闭区间[a,b]中最小的k。如果k不存在,则输出两个0。
样例输入 Sample Input
样例1:
3 2 28
3 2
5 3
7 2
样例2:
3 24 31
3 2
5 3
7 2
样例输出 Sample Output
样例1:
1
23
样例2:
0
0
数据范围及提示 Data Size & Hint
1<=a<=b<=10^14
n<=10
输入保证所有n个质数的乘积<=10^14
每个质数<=1.5*10^9
请无视通过率(被人黑了。。。)
数据保证不会溢出64bit整数
分类标签 Tags 点此展开
暂无标签
题解:
中国剩余定理的模板题。
x ≡ 2(mod 3)
(k模) (质数) (余数)
AC代码:
#include<iostream> #define maxn 11 using namespace std; #define ll long long ll yushu[maxn],mod[maxn]; void excgcd(ll a,ll b,ll &x,ll &y){ if(b==0){ x=1; y=0; return; } ll x1,y1; excgcd(b,a%b,x1,y1); x=y1; y=x1-(a/b)*y1; return; } int main(){ ll s=1,l,r; int n; cin>>n>>l>>r; for(int i=0;i<n;i++){ ll mo,yu; cin>>mo>>yu; yu=yu%mo; s*=mo; yushu[i]=yu; mod[i]=mo; } ll ans=0; for(int i=0;i<n;i++){ ll mi=s/mod[i]; ll x,y; excgcd(mi,mod[i],x,y); ans+=yushu[i]*mi*x; } while(ans>l){ ans-=s; } ll sum=0,minn=0; for(int i=1;;i++){ ans+=s; if(ans<=r){ if(ans>=l){ if(sum==0){ minn=ans; } sum++; } } else break; } cout<<sum<<endl<<minn; return 0; }