【题解】荒岛野人

Question

题目大意:要求一个\(m,\)使得对于任意\(i,j,C_i+xP_i≡C_j+xP_j\mod m\)无解。

\(n<=15,result<=10^6,0<=L_i<=10^6,1<=C_i,P_i<=100.\)

数据范围原题面是错的……

观察到,\(result\)并不大。我们可以枚举模数,对所有方程一个个判断。

注意,判到有解立刻跳出。(我写的双重循环少跳了一个……)

把上面那个式子化一下:

原式化为:\(x(P_i-P_j)≡C_j-C_i\mod m\)

等价于:\(x(P_i-P_j)+my=C_j-C_i\),转化为不定方程形式,可以\(\text{Exgcd}\log\)复杂度求解了。

#include<bits/stdc++.h>
using namespace std;
inline int Exgcd(int a,int b,int &x,int &y){
	if(!b){x=1,y=0;return a;}
	register int res=Exgcd(b,a%b,x,y);
	register int tmp=x;x=y;y=tmp-a/b*y;
	return res;
}
int n,p[20],c[20],l[20];
inline int max(int a,int y){return a>y?a:y;}
int main(){
	scanf("%d",&n);int A=-1;
	for(register int i=1;i<=n;++i)scanf("%d%d%d",&c[i],&p[i],&l[i]),A=max(A,c[i]);
	for(register int M=A;M<=1000001;++M){
		register int flag=0;
		for(register int i=1;i<=n;++i){
			for(register int j=i+1;j<=n;++j){
				register int x,y,P=p[i]-p[j];
				register int G=Exgcd(P,M,x,y);
				register int C=c[j]-c[i];
				if(C%G){continue;}C/=G;
				register int tmp=M/G;
				if(tmp<0)tmp=-tmp;
				x=((x*C)%tmp+tmp)%tmp;
				if(x<=l[i]&&x<=l[j]){flag=1;break;}
			}
			if(flag)break;
		}
		if(!flag){printf("%d\n",M);return 0;}
	}
	return 0;
}

主要可能就是把题意转化为这样形式吧……其实最难的点是它的数据范围)

posted @ 2020-04-13 14:54  Refined_heart  阅读(152)  评论(0编辑  收藏  举报