bzoj 1407 [Noi2002]Savage
阿新 • • 發佈:2018-07-01
php noi2002 using oid class zoj flag 個數 ID
題目:https://www.lydsy.com/JudgeOnline/problem.php?id=1407
因為答案有很小的限制,所以可以枚舉。(聽說不能二分?)
T*p[ i ] + c[ i ] = T*p[ j ] + c[ j ](mod m)
<==>T*(p[ i ] - p[ j ]) + k * m = c[ j ] - c[ i ]
然後需要打一個正確的板子。
放一點筆記:
exgcd有解,僅當得數是gcd的倍數。這樣可以求出特解後同乘一個數得到解。
ax+by=c的通解:ax1+by1=c;ax2+by2=c; -> a(x1-x2)+b(y1-y2)=0; -> a*del(x)+b*del(y)=0
把a和b都除以它們的gcd,得a0*del(x)+b0*del(y)=0;
因為互質,所以最小的del(x)=-b0 , del(y)=a0。
特別奇怪的是如果不判 if (b<0) b = -b 就會WA。可是b什麽時候會變成負數呢?
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int N=20,M=1e6; int n,m,c[N],p[N],l[N],x,y; bool flag; int gcd(int a,int b){return b?gcd(b,a%b):a;} void exgcd(int a,int b) { if(!b){x=1;y=0;return;} exgcd(b,a%b); int tx=x; x=y;y=tx-a/b*y; } int main() { scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%d%d%d",&c[i],&p[i],&l[i]),m=max(m,c[i]);// for(;m<=M;m++) { flag=0; for(int i=1;i<=n;i++) { for(int j=i+1;j<=n;j++) {int a=p[i]-p[j],b=m,w=c[j]-c[i],g=gcd(a,b); if(w%g)continue; a/=g;b/=g;w/=g;// if(b<0)b=-b; // exgcd(a,b); x=(x*w%b+b)%b;//*w,解出來的東西對應得數是gcd,現在約了g,gcd=1,故同乘w if(x<=min(l[i],l[j])){flag=1;break;} } if(flag)break; } if(!flag) { printf("%d",m);return 0; } } }
bzoj 1407 [Noi2002]Savage