• 【BZOJ 1407】[Noi2002]Savage ExGCD


    我bitset+二分未遂后就来用ExGCD了,然而这道题的时间复杂度还真是玄学......

    我们枚举m然后对每一对用ExGCD判解,我们只要满足在最小的一方死亡之前无解就可以了,对于怎么用,就是ax+by=c,在这里c是距离差,a是速度差,b是m,x是我们要的解,y随意。

    时间复杂度O(m*n*n*log),然而这是标解..........

    #include <cstdio>
    int prob[120][3],len,n,c[16],p[16],l[16],S;
    inline int Min(int x,int y){
      return x<y?x:y;
    }
    inline int Max(int x,int y){
      return x>y?x:y;
    }
    inline int GCD(int x,int y){
      return x==0?y:GCD(y%x,x);
    }
    void ExGCD(int a,int &x,int b,int &y){
      if(!b){
        x=1,y=0;
        return;
      }
      ExGCD(b,x,a%b,y);
      int temp=x;
      x=y,y=temp-a/b*y;
    }
    int main(){
      freopen("savage.in","r",stdin);
      freopen("savage.out","w",stdout);
      scanf("%d",&n);
      for(int i=1;i<=n;i++)
        scanf("%d%d%d",&c[i],&p[i],&l[i]);
      for(int i=1;i<=n;i++){
        for(int j=i+1;j<=n;j++){
          prob[++len][0]=c[i]-c[j],
          prob[len][1]=p[j]-p[i],
          prob[len][2]=Min(l[i],l[j]);
          if(prob[len][1]<0)
            prob[len][1]*=-1,prob[len][0]*=-1;
        }
        S=Max(S,c[i]);
      }
      for(int m=S;m<=1000000;m++){
        bool god=1;
        for(int i=1;i<=len;i++){
          int gcd=GCD(prob[i][1],m);
          if(prob[i][0]%gcd==0){
            int x,y;
            ExGCD(prob[i][1],x,m,y);
            x=x*prob[i][0]/gcd;
            int t=m/gcd;
            x=(x%t+t)%t;
            if(x<=prob[i][2]){
              god=0;
              break;
            }
          }
        }
        if(god){
          printf("%d",m);
          return 0;
        }
      }
    }
  • 相关阅读:
    25-k个一组翻转链表 203-移除链表元素 206-反转一个链表
    24. 两两交换链表中的节点
    23-合并K个升序链表
    19-删除链表的倒数第N个节点
    18-四数之和
    21-合并两个有序链表
    双指针
    16-最接近的三数之和
    15-三数之和
    RobotFramework 断言关键字
  • 原文地址:https://www.cnblogs.com/TSHugh/p/7363018.html
Copyright © 2020-2023  润新知