• POJ2891 Strange Way to Express Integers【扩展中国剩余定理】


    题目大意

    就是模板。。。没啥好说的

    思路

    因为模数不互质,所以直接中国剩余定理肯定是不对的
    然后就考虑怎么合并两个同余方程
    (ans = a_1 + x_1 * m_1 = a_2 + x_2 * m_2)
    (x_1 * m_1 + x_2 * m_2 = a _ 2 - a _ 1)(因为正负号没影响嘛)
    然后就可以exgcd解出来(x_1, x_2), 最后就可以得到(x' = a_1 + x_1 * m_1, m' = lcm(m_1, m_2))
    然后就不停合并就可以了


    //Author: dream_maker
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<iostream>
    using namespace std;
    //----------------------------------------------
    //typename
    typedef long long ll;
    //convenient for
    #define fu(a, b, c) for (int a = b; a <= c; ++a)
    #define fd(a, b, c) for (int a = b; a >= c; --a)
    #define fv(a, b) for (int a = 0; a < (signed)b.size(); ++a)
    //inf of different typename
    const int INF_of_int = 1e9;
    const ll INF_of_ll = 1e18;
    //fast read and write
    template <typename T>
    void Read(T &x) {
      bool w = 1;x = 0;
      char c = getchar();
      while (!isdigit(c) && c != '-') c = getchar();
      if (c == '-') w = 0, c = getchar();
      while (isdigit(c)) {
        x = (x<<1) + (x<<3) + c -'0';
        c = getchar();
      }
      if (!w) x = -x;
    }
    template <typename T>
    void Write(T x) {
      if (x < 0) {
        putchar('-');
        x = -x; 
      }
      if (x > 9) Write(x / 10);
      putchar(x % 10 + '0');
    }
    //----------------------------------------------
    const int N = 1e5 + 5;
    ll n, a[N], m[N];
    ll gcd(ll a, ll b) {
      return b ? gcd(b, a % b) : a;
    }
    void exgcd(ll a, ll b, ll &x, ll &y) {
      if (!b) {x = 1, y = 0; return;}
      exgcd(b, a % b, y, x);
      y -= a / b * x;
    }
    ll exCRT() {
      ll M = m[1], A = a[1];
      fu(i, 2, n) {
        ll d = gcd(M, m[i]), x, y;
        if ((a[i] - A) % d) return -1;
        exgcd(M, m[i], x, y);
        x *= (a[i] - A) / d;
        x = (x % (m[i] / d) + (m[i] / d)) % (m[i] / d);
        A += M * x, M = M / d * m[i], A %= M; 
      }
      if (A < 0) A += M;
      return A;
    }
    int main() {
      while (scanf("%lld", &n) != EOF){
        fu(i, 1, n) Read(m[i]), Read(a[i]);
        Write(exCRT());
        putchar('
    ');
      }
      return 0;
    }
    
  • 相关阅读:
    转载:AAC编解码概述
    转载:ADTS header
    wcf寄宿在iis上的跨域访问问题【不止是添加跨域文件】
    转 http 分析工具
    时间管理1
    关于silverlight和Wcf分布式部署注意问题(收藏夹)
    c#修改xml文件
    关于在线编辑的异常
    创业文摘5--从程序员转向企业家的10个建议
    silverlight 后台代码生成gridview
  • 原文地址:https://www.cnblogs.com/dream-maker-yk/p/9832310.html
Copyright © 2020-2023  润新知