【EXCRT模板】POJ2891/LuoGu4777Strange Way to Express Integers拓展中国剩余定理

这道题需要exgcd的基础

POJ的题干描述十分恶心

Strange Way to Express Integers
Time Limit: 1000MS        Memory Limit: 131072K
Total Submissions: 21217        Accepted: 7120
Description

Elina is reading a book written by Rujia Liu, which introduces a strange way to express non-negative integers. The way is described as following:
Choose k different positive integers a1, a2, …, ak. For some non-negative m, divide it by every ai (1 ≤ i ≤ k) to find the remainder ri. If a1, a2, …, ak are properly chosen, m can be determined, then the pairs (ai, ri) can be used to express m.

“It is easy to calculate the pairs from m, ” said Elina. “But how can I find m from the pairs?”

Since Elina is new to programming, this problem is too difficult for her. Can you help her?

Input

The input contains multiple test cases. Each test cases consists of some lines.

Line 1: Contains the integer k.
Lines 2 ~ k + 1: Each contains a pair of integers ai, ri (1 ≤ i ≤ k).
Output

Output the non-negative integer m on a separate line for each test case. If there are multiple possible values, output the smallest one. If there are no possible values, output -1.

Sample Input

2
8 7
11 9
Sample Output

31
Hint

All integers in the input and the output are non-negative and can be represented by 64-bit integral types.

Source

POJ Monthly--2006.07.30, Static
POJ2891

还是洛谷的好,题意就是同模方程组(模数不互质)

洛谷POJ区别就是POJ有判断误解和多组数据(POJ传统,好多多组数据)

这种最重要的就是推导过程了

网上还是很多的,我就再赘述一遍

x = r1(% a1)

x = r2(%a2)

即x = k1*a1*+r1 = k2*a2+r2

移项k1*a1 = k2*a2+r2-r1(%a2)

扫描二维码关注公众号,回复: 4398633 查看本文章

同模a2,即k1*a1 = r2-r1(%a2)

这里用exgcd,求出k1通解即k1 = k0+a2/gcd(a,b)*t

带入,也就是x = a1*k1+r1 = a1*(k0+a2/gcd(a,b)*t)+r1 = a1*k0+lcm(a,b)+r1

同模一个lcm(a1,a2)即a1*k0+r1 = x(%lcm(a1,a2))

这样我们就每次用一个exgcd可以把方程合并了(复杂度应该是nlogn)

同模方程组无解就是exgcd无解,判断下就好了

注意:

1.发现无解之后不可以break,因为数据还没有读完就进行下一组,肯定是错的

2.POJ此题没有数据范围,也就是说本题最好不要离线,只要先读入一个数,然后在线搞即可(时间相差不大,只是快了一点但是省内存,原来蒟蒻的我2.27MB,现在还是蒟蒻的我在线搞0.86MB)

好了上代码

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 typedef long long ll;
 6 ll n,a,r,x,y;bool flag=0;
 7 inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
 8 inline ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
 9 ll ksc(ll a,ll b,ll mod)
10 {
11     ll fina=0;int kk=1;
12     if(a<0)a=-a,kk=-kk;
13     if(b<0)b=-b,kk=-kk;
14     while(b)
15     {
16         if(b%2)fina=(fina+a)%mod;
17         a=(a+a)%mod,b=b/2;
18     }
19     return fina%mod*kk;
20 } 
21 void exgcd(ll a,ll b)
22 {
23     if(!b)
24         x=1,y=0;
25     else
26     {
27         exgcd(b,a%b);
28         ll tt=x;
29         x=y,y=tt-a/b*x;
30     }
31 }
32 int main()
33 {
34     while(scanf("%lld",&n)==1 && n)
35     {
36         flag=0;
37         scanf("%lld%lld",&a,&r);
38         for(register ll i=1,a1,r1,gc,aa,bb,cc;i<n;i++)
39         {
40             a1=a,r1=r;
41             scanf("%lld%lld",&a,&r);
42             aa=a1,bb=a,cc=r-r1,gc=gcd(aa,bb);
43             if(cc%gc){flag=1;continue;}
44             aa/=gc,bb/=gc,cc/=gc;
45             exgcd(aa,bb);
46             r=(ksc(x,cc,bb)+bb)%bb*a1+r1;
47             a=lcm(a1,a);
48         }
49         if(flag){puts("-1");continue;}
50         ll aa=1,bb=a,cc=r;
51         exgcd(aa,bb);
52         printf("%lld\n",(ksc(x,cc,bb)+bb)%bb);
53     }
54     return 0;
55 }

猜你喜欢

转载自www.cnblogs.com/Qin-Wei-Kai/p/10079603.html