zoukankan      html  css  js  c++  java
  • cf338 D GCD Table

    传送门
    给出n和m表示矩阵大小,矩阵的值是(gcd(i,j))
    再给出k个长度的序列,请问,这个序列是否在矩阵中出现过

    对于在n*m的矩阵找,那么必定需要先找到横坐标,然后在这个横坐标里找k个数字
    发现如果说横坐标是(lcm(a_i)),是可能存在解的
    假设这一行存在序列([x + i, x + k]),那么((x + i) \% a[i] == 0)才能存在解
    那么久得到了k个同余方程,(xequiv -i (mod a[i]))
    a[i]是不一定两两互质的非负整数,那么找到一个最小x
    最后判断下这个区间的值是否是a即可

    #include <iostream>
    #include <cstdio>
    #define ll long long
    using namespace std;
    const int N = 1e5 + 5;
    void ex_gcd(ll a, ll b, ll &d, ll &x, ll &y){
        if(b == 0){
            d = a,x = 1,y = 0;
            return;
        }
        ex_gcd(b, a % b, d, y, x);
        y -= x * (a / b);
    }
    inline ll mull(ll a, ll b, ll p) {
        return (a * b - (ll)((long double)a / p * b) * p + p) % p;
    }
    ll ex_china(ll a[], ll m[], int n){//x = a(mod m)
        ll M = m[1];
        ll ans = a[1];
        ll d, x, y;
        for(int i = 2; i <= n; i++){
            ll c = ((a[i] - ans) % m[i] + m[i]) % m[i];
            ex_gcd(M, m[i], d, x, y);
            if(c % d)return -1;//不存在解的情况
            ll mod = m[i] / d;
            x = mull(x, c / d, mod);
            ans += x * M;
            M *= mod;
            ans = (ans % M + M) % M;
        }
        // return ans > 0? ans : ans + M;//注意ans是M倍数时输出M
        return ans;
    }
    ll gcd(ll a, ll b){
        return b == 0 ? a : gcd(b, a % b);
    }
    ll LCM(ll a, ll b){
        return a / gcd(a, b) * b;
    }
    ll x[N], a[N], mm[N];
    int main(){
        ll n, m, k;
        scanf("%lld%lld%lld", &n, &m, &k);
        ll lcm = 1;
        for(int i = 1; i <= k; i++) {
            scanf("%lld", &x[i]);
            lcm = LCM(lcm, x[i]);
        }
        if(lcm > n || lcm < 1) {
            printf("NO
    ");
        }else {
            for(int i = 1; i <= k; i++) {
                a[i] = -i;
                mm[i] = x[i];
            }
            ll xxx = ex_china(a, mm, k);
            if(xxx < 0 || xxx + k > m) {
                printf("NO
    "); return 0;
            }
            for(ll j = 1; j <= k; j++) {
                if(gcd(lcm, j + xxx) != x[j]) {
                    printf("NO
    ");
                    return 0;
                }
            }
            printf("YES
    ");
        }
        return 0;
    }
    
  • 相关阅读:
    剑指 Offer 31. 栈的压入、弹出序列
    【笔记】小样本学习(Few-shot Learning)(1)
    【VS】Visual Studio 自带的反编译工具,方便了太多了。
    秋招提前批已来,万字长文教你如何增加面试大厂的成功率🔥
    Spring Boot自动配置原理与实践(二)
    MySQL是怎么解决幻读问题的?
    深入学习Netty(5)——Netty是如何解决TCP粘包/拆包问题的?
    深入学习Netty(4)——Netty编程入门
    HttpRunner3.X
    HttpRunner3.X
  • 原文地址:https://www.cnblogs.com/Emcikem/p/13439451.html
Copyright © 2011-2022 走看看