BZOJ-1407 [Noi2002]Savage(exgcd)
阿新 • • 發佈:2020-12-06
題目描述
資料範圍:\(1\leq n\leq 15,1\leq C_i,P_i\leq 100,0\leq L_i\leq 10^6\),輸入資料保證有解,且 \(M\leq 10^6\)。
分析
給出 \(n\) 組 \(C_i,P_i,L_i\),求最小的 \(M\) 使得對於任意的 \(i,j(1\leq i,j\leq n)\)
\[C_i+P_i\times x\equiv C_j+P_j\times x\pmod {M} \]不成立。
則:
\[C_i+P_i\times x+My=C_j+P_j\times x\\(P_i-P_j)x+My=C_j-C_i \]\(M\)
時間複雜度 \(O(Mn^2\log C_i)\)。
程式碼
#include<bits/stdc++.h> using namespace std; int n; long long C[1010],P[1010],L[1010]; long long exgcd(long long a,long long b,long long &x,long long &y) { if(!b) { x=1; y=0; return a; } long long gcd=exgcd(b,a%b,y,x); y=y-x*(a/b); return gcd; } bool check(int M) { for(int i=1;i<=n;i++) { for(int j=i+1;j<=n;j++) { long long a=P[i]-P[j]; long long b=M; long long c=C[j]-C[i]; long long x,y; long long gcd=exgcd(b,a%b,y,x); if(c%gcd!=0) continue; a=a/gcd;b=b/gcd;c=c/gcd; if(b<0) b=-b; x=(x*c%b+b)%b; if(x<=L[i]&&x<=L[j]) return 0; } } return true; } int main() { cin>>n; long long maxn=0; for(int i=1;i<=n;i++) { scanf("%d %d %d",&C[i],&P[i],&L[i]); maxn=max(maxn,C[i]); } for(int i=maxn;;i++) { if(check(i)) { printf("%d\n",i); return 0; } } return 0; }