zoukankan      html  css  js  c++  java
  • 【数学 exgcd】bzoj1407: [Noi2002]Savage

    exgcd解不定方程时候$abs()$不能乱加

    Description

    Input

    第1行为一个整数N(1<=N<=15),即野人的数目。
    第2行到第N+1每行为三个整数Ci, Pi, Li表示每个野人所住的初始洞穴编号,每年走过的洞穴数及寿命值。
    (1<=Ci,Pi<=100, 0<=Li<=10^6 )

    Output

    仅包含一个数M,即最少可能的山洞数。输入数据保证有解,且M不大于10^6。

    Sample Input

    3
    1 3 4
    2 7 3
    3 2 1

    Sample Output

    6
    //该样例对应于题目描述中的例子。

    题目分析

    注意到$n$很小且保证$M≤10^6$,自然想到枚举答案对不对!其实枚举答案的复杂度是不对的但是就是可过(因为$n^2$的验证大多数情况达不到上界;出题人的本意大概也是枚举吧)

    $O(M)$枚举答案之后考虑如何验证。两个野人当总洞穴数为$M'$时在有生之年相遇即$C_i+time*P_i≡C_j+time*P_j(modM')$,其中$time≤min{L_i,L_j}$。那么这个式子就可以展开后作为不定方程求解了。注意最后要将特解变化为最小正整数解。

    这里要说的时,求解不定方程时,即使部分会出现负数情况,也不能够乱加$abs()$!因为符号的正负性在之后的方程中会被负负得正或保持符号。唯一要$abs()$的就是最后求最小正整数解时的变换。

    哦这题枚举答案还要从$mx$开始,因为有部分情况会出现$M'<mx$在表达式上合法的情况。

     1 #include<bits/stdc++.h>
     2 
     3 int n,c[23],p[23],l[23],mx;
     4 
     5 void exgcd(int a, int b, int &x, int &y)
     6 {
     7     if (b==0){
     8         x = 1, y = 0;
     9         return;
    10     }
    11     exgcd(b, a%b, y, x);
    12     y -= a/b*x;
    13 }
    14 int gcd(int x, int y){return y==0?x:gcd(y, x%y);}
    15 int abs(int x){return x>0?x:-x;}
    16 bool able(int ts)
    17 {
    18     register int i,j,ci,cj,pi,pj,lt,d,mt;
    19     for (i=1; i<=n; i++)
    20         for (j=i+1; j<=n; j++)
    21         {
    22             int x,y;
    23             ci = c[i], cj = c[j], pi = p[i], pj = p[j], lt = std::min(l[i], l[j]);
    24             d = gcd(pi-pj, ts);
    25             if ((cj-ci)%d) continue;
    26             exgcd(pi-pj, ts, x, y);
    27             mt = abs(ts/d), x = ((x*(cj-ci)/d)%mt+mt)%mt;
    28             if (x <= lt) return 0;
    29         }
    30     return 1;
    31 }
    32 int main()
    33 {
    34     scanf("%d",&n);
    35     for (int i=1; i<=n; i++) scanf("%d%d%d",&c[i],&p[i],&l[i]), mx = mx>c[i]?mx:c[i];
    36     for (int m=mx; m<=1000000; m++)
    37         if (able(m)){
    38             printf("%d
    ",m);
    39             return 0;
    40         }
    41     return 0;
    42 }

    END

  • 相关阅读:
    git 学习笔记
    单选框和复选框的样式修改
    es6常用方法
    js混杂笔记
    Entity Framework 学习第一天
    sublime text2的插件熟悉
    近况
    thinkphp ,进行关联模型的时候出现的问题,版本是3.2
    上传图片的权限问题
    今天学习了下,如何破解wifi
  • 原文地址:https://www.cnblogs.com/antiquality/p/9367488.html
Copyright © 2011-2022 走看看