• CF 338 D GCD Table(CRT)


    转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents    by---cxlove

    给定一个序列,a[1 。。k],问是否存在(i , j)使得 GCD(i , j + r - 1) = a[r]  (k>=r >=1),其中 i <= n && j + k - 1 <= m

    http://codeforces.com/contest/338/problem/D

    首先容易知道row = lcm (a[1……k]),是最小可能存在解的行。

    官方题解中有证明,反正乱七八糟的。。。我太弱了,看不懂

    之后我们找到最小的col满足

    col % a[1] = 0

    (col + 1) % a[2] = 0

    ……

    (col + k - 1) % a[k] = 0

    这个东西用CRT求出来。

    最后check一下row , col是否满足,就结束了。。。

    显然j < col 是不可能满足的,而且col + x * row肯定也是可能满足的。

    当然可能存在gcd (col + r - 1 , row) > a[r]。

    所以col缩小是肯定不满足的,而即使你增大col若干倍,只可能使得偏差更大。

    接下来就注意一下各种细节,比如溢出等问题

    #include <iostream>
    #include <queue>
    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    #define lson step << 1
    #define rson step << 1 | 1
    using namespace std;
    typedef long long LL;
    const int N = 10005;
    LL n , m , a[N] , row = 1LL;
    int k;
    LL gcd (LL a , LL b) {
        return b == 0 ? a : gcd (b , a % b);
    }
    LL extend_gcd (LL a , LL b , LL &x , LL &y) {
        if (b == 0) {
            x = 1LL;
            y = 0;
            return a;
        }
        LL g = extend_gcd (b , a % b , x , y);
        LL t = x;
        x = y; y = t - a / b * x;
        return g;
    } 
    int main() {
        int t;
        #ifndef ONLINE_JUDGE
            freopen ("input.txt" , "r" , stdin);
            // freopen ("output.txt" , "w" , stdout);
        #endif
        cin >> n >> m >> k;
        for (int i = 0 ; i < k ; i ++) {
            cin >> a[i];
            row = row / gcd (row , a[i]) * a[i];
            if (row <= 0 || row > n) {
                puts ("NO");
                return 0;
            }
        }
        // Z = u + v * x
        LL u = 0LL , v = a[0];
        for (int i = 1 ; i < k ; i ++) {
            // Z = U + V * x1
            // Z = - i + a[i] * x2
            // v * x - a[i] * y = - u - i
            // A * x + B * y = C
            LL x , y , A = v , B = -a[i] , C = - u - i;
            LL g = extend_gcd (A , B , x , y);
            if (C % g) {
                puts ("NO");
                return 0;
            }
            if (B % g) puts ("ERROR");
            LL t = B / g;
            x = x * (C / g);
            x = (x % t + t) % t;
            if (x < 0) x -= t;
            // y = (C - A * x) / B;
            u = u + v * x;
            v = v / gcd (v , a[i]) * a[i];
        }
        if (u == 0) u += row;
        if (u + k - 1 > m) {
            puts ("NO");
            return 0;
        }
        for (int i = 0 ; i < k ; i ++) {
            if (gcd (row , u + i) != a[i]) {
                puts ("NO");
                return 0;
            }
        }
        puts ("YES");
        return 0;
    }   



  • 相关阅读:
    C#编写ActiveX在WEB中应用
    Asp.net中Array的用法
    CAB打包方法
    C#获取文件路径的几种方法
    使用MakeCAB.exe命令创建CAB文件
    VS2005 工具里添加“OLE/COM 对象查看器”命令
    【转载】ASP.NET MVC中Controller与View之间的数据传递总结
    F如何配置外向交货单的定价过程
    解决 局域网XP无权限访问的问题 (转)
    U盘装XP系统(含截图,2012最新原创超简单方法)
  • 原文地址:https://www.cnblogs.com/pangblog/p/3268874.html
Copyright © 2020-2023  润新知