題目:java
His majesty chatted with Han Xin about the capabilities of the generals. Each had their shortcomings. His majesty asked, ``How many troops could I lead?" Han Xin replied, ``Your highness should not lead more than 100000." His majesty said, ``And what about you?" ``For your humble servant, the more the merrier!" said Han Xin.
---Records of the Grand Historian
Han Xin was a military general who served Liu Bang during the Chu-Han contention and contributed greatly to the founding of the Han dynasty. Your friend, in a strange coincidence, also named Han Xin, is a military general as well.
One day you asked him how many troops he led. He was reluctant to tell you the exact number, but he told you some clues in certain form, for example:ios
連接:https://ac.nowcoder.com/acm/contest/890/D
來源:牛客網ide
3 100 3 2 5 3 7 2
23
4 10000 12 7 15 2 30 5 8 6
he was definitely lying
2 10 11 3 19 7
he was probably lying
題目大意:韓信點兵,給你n個結果,兵隊總數%ai=bi,而後求出最後兵隊最少到底有多少人。
若是這個數不存在,輸出he was definitely lying
若是數量大於給定的門檻m,輸出he was probably lying,不然出輸出人數。
題解:由於最後的餘數並非徹底互質,因此須要使用擴展中國剩餘定理。
還有一個坑,就是這些餘數可能徹底互質,因此最後的M會特別特別大,
我以前使用的是洛谷中國剩餘定理模板題的第一個模板,就是由於M特別大,
改寫成了java,用大數作就過了。寫的有點醜,不要介意。
import java.util.*; import java.math.*; import java.security.MessageDigest; public class Main { static int n; static BigInteger m,x,y; static BigInteger[] ai=new BigInteger[200]; static BigInteger[] bi=new BigInteger[200]; public static void main(String[] args) { Scanner cin=new Scanner(System.in); n=cin.nextInt(); m=cin.nextBigInteger(); for(int i=1;i<=n;i++) { bi[i]=cin.nextBigInteger(); ai[i]=cin.nextBigInteger(); } BigInteger ans = excrt(); long flag=-1; if (ans.compareTo(BigInteger.valueOf(flag))==0) System.out.print("he was definitely lying\n"); else if(ans.compareTo(m)!=-1&&ans.compareTo(m)!=0) System.out.print("he was probably lying\n"); else System.out.print(ans); } public static BigInteger excrt() { BigInteger k; BigInteger ans = ai[1]; BigInteger M=bi[1]; for (int i = 2; i <= n; i++) { BigInteger a = M, b = bi[i]; BigInteger c=ai[i].subtract(ans.mod(b)).add(b).mod(b); BigInteger gcd = exgcd(a, b), bg = b .divide(gcd); long flag=-1; if (c.mod(gcd).compareTo(BigInteger.ZERO)!=0) return BigInteger.valueOf(flag); x = mul(x,c.divide(gcd), bg); ans=ans.add(x.multiply(M)); M =M.multiply(bg); ans = (ans.mod(M).add(M)).mod(M); } return (ans.mod(M).add(M)).mod(M); } public static BigInteger mul(BigInteger a, BigInteger b, BigInteger mod) { BigInteger res = BigInteger.ZERO; while (b.compareTo(BigInteger.ZERO)>0) { if (b.mod(BigInteger.valueOf((long)2)).compareTo(BigInteger.ZERO)>0) res = res.add(a).mod(mod); a = a.add(a).mod(mod); b = b.divide(BigInteger.valueOf((long)2)); } return res; } public static BigInteger exgcd(BigInteger a, BigInteger b) { if (b.compareTo(BigInteger.ZERO)==0) { x = BigInteger.ONE; y = BigInteger.ZERO; return a; } BigInteger gcd = exgcd(b, a.mod(b)); BigInteger tp = x; x = y; y = tp.subtract(a.divide(b).multiply(y)); return gcd; } }
貼一下洛谷模板題:https://www.luogu.org/problem/P4777oop
模板來源:https://blog.csdn.net/niiick/article/details/80229217spa
C++模板代碼:.net
//niiick #include<iostream> #include<vector> #include<algorithm> #include<queue> #include<cstring> #include<cstdio> using namespace std; typedef long long lt; lt read() { lt f=1,x=0; char ss=getchar(); while(ss<'0'||ss>'9'){if(ss=='-')f=-1;ss=getchar();} while(ss>='0'&&ss<='9'){x=x*10+ss-'0';ss=getchar();} return f*x; } const int maxn=100010; int n; lt ai[maxn],bi[maxn]; lt mul(lt a,lt b,lt mod) { lt res=0; while(b>0) { if(b&1) res=(res+a)%mod; a=(a+a)%mod; b>>=1; } return res; } lt exgcd(lt a,lt b,lt &x,lt &y) { if(b==0){x=1;y=0;return a;} lt gcd=exgcd(b,a%b,x,y); lt tp=x; x=y; y=tp-a/b*y; return gcd; } lt excrt() { lt x,y,k; lt M=bi[1],ans=ai[1];//第一個方程的解特判 for(int i=2;i<=n;i++) { lt a=M,b=bi[i],c=(ai[i]-ans%b+b)%b;//ax≡c(mod b) lt gcd=exgcd(a,b,x,y),bg=b/gcd; if(c%gcd!=0) return -1; //判斷是否無解,然而這題其實不用 x=mul(x,c/gcd,bg); ans+=x*M;//更新前k個方程組的答案 M*=bg;//M爲前k個m的lcm ans=(ans%M+M)%M; } return (ans%M+M)%M; } int main() { n=read(); for(int i=1;i<=n;++i) bi[i]=read(),ai[i]=read(); printf("%lld",excrt()); return 0; }