【题目背景】
露娜的好朋fu友qin猪哥哥是一个屌丝科学家,他发明出了一个可以进行空间跳跃的机器,露娜将作为第一个乘客进行时空跳跃之旅。她将地点定位于佩奇的家。嗖!
露娜来到佩奇的家中,佩奇一家热情地招待了她,她在佩奇家愉快地玩耍,这期间还学会了花样跳泥坑,种恐龙。时光荏苒,很快到了露娜返程的日子。她提取了佩奇的基因,猪哥哥帮助她克隆出了许多佩奇。
露娜的另一个好朋er友zi——精致的猪猪女孩萝萝,也是一个喜欢佩奇的人,有一天,她来参观露娜的佩奇欢乐草原,并且想知道这里佩奇的数量。但是由于萝萝是一个快要进国大的女孩,露娜想出一道题考考她,看看萝萝是否有资质将露娜带飞。
【题目描述】
举个例子,假如有16只佩奇,如果建了3个小屋,剩下1只佩奇就没有地方安家了。如果建造了5个小屋,但是仍然有1只佩奇没有地方去,然后如果建造了7个小屋,还有2只佩奇没有地方去。萝萝思考了一会,得出了答案!
输入
第一行包含一个整数n (n <= 10) – 建立小屋的次数,解下来n行,每行两个整数ai, bi( bi <= ai <= 1000), 表示建立了ai个小屋,有bi只佩奇没有去处。你可以假定ai,aj互质.
输出
输出包含一个正整数,即为露娜至少养佩奇的数目。
样例输入
3
3 1
5 1
7 2
样例输出
16
【胡乱分析】
尽管题目描述的天花乱坠,但板子题就是板子题。
这道题涉及到了数论基础中的一些内容,下面进行讲解与证明。(巨佬就别看了。。。)
[exgcd]
对于a,b(a>b)一定存在整数x,y使得xa+yb=gcd(a,b)
(1)当b为0时,gcd(a,b)=a。此时有x=1,y=0;
(2)当a>b>0时,
设ax1+by1=gcd(a,b)
bx2+(a%b)y2=gcd(b,a%b)
∵gcd(a,b)=gcd(b,a%b)
∴ax1+by1=bx2+(a%b)y2
∵a%b=(a-[a/b]y2)
∴ax1+by1=bx2+(a-[a/b]*b)y2
∴ax1+by2=bx2+ay2-[a/b]*by2
∴ax1+by2=ay2+b(x2-[a/b]*y2)
即得x1=y2,y1=x2-[a/b]*y2。
如果c|gcd(a,b)则ax+by=c一定有整数解。
代码如下
1 int exgcd(long long a,long long b,long long &x,long long &y) 2 { 3 if(b==0) 4 { 5 x = 1; 6 y = 0; 7 return a; 8 } 9 int d = exgcd(b,a%b,y,x) 10 y-=a/b*x; 11 return d; 12 }
然后是中国剩余定理。这个代码我没弄太懂也只能背板子了。那么它的思路就是,,,就是,,,就是,,
求x满足x%3 == 2;x%5==3;x%7==2; 令x1=k*lcm(5,7)使得x1%3==1,同理x2 = k*lcm(3,7) x2%5==1, x3 = k*lcm(3,5) x3%7==1,(k∈N*)则x=(x1*2+x2*3+x3*2)%(3*5*7)。
对于上述操作一些有疑问的地方的讲解:x=(x1*2+x2*3+x3*2)%(3*5*7)中的2,3,2,分别对应着那些余数,这里用到一个定理(还是推理)是”如果a%b=c 那么(a*k)%b=kc“。这样大家就懂了叭。
那么它的板子如下
1 //中国剩余定理 ,r[]存放余数 ,prime[]存放两两互质的数 2 int Chinese_Remainder(int r[],int prime[],int len) 3 { 4 int i,d,x,y,m,n=1,sum=0; 5 //计算所以除数的积n,也是所以除数的最小公倍数 6 for(i=0;i<len;i++) 7 n*=prime[i]; 8 //计算符合所以条件的数 9 for(i=0;i<len;i++) 10 { 11 m=n/prime[i];//计算除去本身的所有除数的积m 12 d=exgcd(prime[i],m,x,y);//计算w[i]*x+m*y=gcd(w[i],m)的一个解y 13 //累加整数解y的同并不断对n取余,其利用公式:(a+b)%c=(a%c+b%c)%c 14 sum=(sum+y*m*r[i])%n; 15 } 16 return (n+sum%n)%n;//满足所以方程的最小解 17 }
从某神ben那里巴拉来的。
然后这是gg给的标程
1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 #define N 5050 5 typedef long long LL; 6 LL m[N]; 7 LL M=1,n,ans; 8 LL t[N],Mn[N],MM[N]; 9 10 LL exgcd(LL a,LL b,LL &x,LL &y) 11 { 12 if(b==0) 13 { 14 x=1,y=0;return a; 15 } 16 else 17 { 18 LL t=exgcd(b,a%b,y,x); 19 y-=x*(a/b); 20 return t; 21 } 22 } 23 24 LL CRT() 25 { 26 LL temp; 27 for(LL i=1;i<=n;i++) 28 { 29 MM[i]=M/m[i]; 30 LL k=exgcd(MM[i],m[i],Mn[i],temp); 31 ans+=(MM[i]*Mn[i]*t[i]); 32 } 33 return ((ans%M)+M)%M; 34 } 35 36 int main() 37 { 38 freopen("cao.in","r",stdin); 39 freopen("cao.out","w",stdout); 40 cin>>n; 41 for(LL i=1;i<=n;i++) 42 { 43 scanf("%d%d",&m[i],&t[i]); 44 M*=m[i]; 45 } 46 47 cout<<CRT()<<endl; 48 49 return 0; 50 }
end.