BZOJ1407: [Noi2002]Savage

来源:互联网 发布:淘宝背景材图 编辑:程序博客网 时间:2024/05/29 11:50

BZOJ1407

直接枚举m,然后n2判断。
为了方便处理,将所有Ci先-1.
对于任意两个野人i,j,令他们第x天相遇
则有(Ci+xpi)mod M=(Cj+xpj)mod M
(CiCj)=x(pjpi)mod M
可以列出方程(pjpi)x+My=(CiCj)
方程无解或者x最小非负整数解<=min(Li,Lj),则满足。
exgcd解出的x,y(pjpi)x+My=Gcd((pjpi),M)
所以求得的x0=x(CiCj)gcd
通解X=x0+Mgcdk
所以最小非负整数解为(x0+Mgcd)mod Mgcd
注意开始位置要从Max(Ci)+1开始

【代码】

#include <cstdio>#include <iostream>#include <algorithm>#define N 100005#define Mod 999911659#define INF 0x7fffffffusing namespace std;typedef long long ll;ll read(){    ll x=0,f=1;char ch=getchar();    while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}    while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}    return x*f;}int n,ans,mn;int C[N],P[N],L[N];void Exgcd(int a,int b,int &d,int &x,int &y) {    if(b) {        Exgcd(b,a%b,d,y,x);        y-=(a/b)*x;    }    else x=1,y=0,d=a;}int Check(int i,int j,int M){    int x,y,d;    int a=(P[j]-P[i]+M)%M,b=(C[i]-C[j]+M)%M;    Exgcd(a,M,d,x,y);    if(b%d) return INF;    x*=b/d;M/=d;    return (x%M+M)%M;}bool Judge(int M){    for(int i=1;i<=n;i++)    for(int j=1;j<i;j++) if(Check(i,j,M)<=min(L[i],L[j]))         return false;    return true;}int main(){       n=read();    for(int i=1;i<=n;i++) C[i]=read()-1,P[i]=read(),L[i]=read(),mn=max(mn,C[i]);    for(int x=mn+1;x<=1e6;x++) if(Judge(x))     {        printf("%d\n",x);        return 0;    }    return 0;}
原创粉丝点击