• ABC254 F - Rectangle GCD( 数据结构&&gcd)


    题目

    传送门

    题意:

    给你两个数组 A , B A,B A,B
    生成一个矩阵:位置 ( i , j ) (i,j) (i,j)的值为 A i + B j A_i+B_j Ai+Bj

    询问q次,每次询问一个子矩阵的gcd

    思路:

    step1:

    弱化下问题:假如是询问q次区间gcd?
    那么我们可以考虑用线段树优化或者rmq

    step2:

    • 先看一行的计算结果:
      g c d ( A x 1 + B y 1 , A x 1 + B y 1 + 1 , . . . , A x 1 + B y 2 ) gcd(A_{x_1} + B_{y_1},A_{x_1} + B_{y_1+1},...,A_{x_1} + B_{y_2}) gcd(Ax1+By1,Ax1+By1+1,...,Ax1+By2)
      根据差分,转换为
      g c d ( A x 1 + B y 1 , B y 1 + 1 − B y 1 , . . . , B y 2 − B y 2 − 1 ) gcd(A_{x_1} + B_{y_1}, B_{y_1+1} - B_{y_1},..., B_{y_2} - B_{y_2-1}) gcd(Ax1+By1,By1+1By1,...,By2By21)

    我们发现根据step1,我们可以快速计算出一行的结果。

    • 看多行的结果:

    g c d ( A x 1 + B y 1 , A x 1 + B y 1 + 1 , . . . , A x 1 + B y 2 ) gcd(A_{x_1} + B_{y_1},A_{x_1} + B_{y_1+1},...,A_{x_1} + B_{y_2}) gcd(Ax1+By1,Ax1+By1+1,...,Ax1+By2)
    g c d ( A x 1 + 1 + B y 1 , A x 1 + 1 + B y 1 + 1 , . . . , A x 1 + 1 + B y 2 ) gcd(A_{x_1+1} + B_{y_1},A_{x_1+1} + B_{y_1+1},...,A_{x_1+1} + B_{y_2}) gcd(Ax1+1+By1,Ax1+1+By1+1,...,Ax1+1+By2)

    g c d ( A x 2 + B y 1 , A x 2 + B y 1 + 1 , . . . , A x 2 + B y 2 ) gcd(A_{x_2} + B_{y_1},A_{x_2} + B_{y_1+1},...,A_{x_2} + B_{y_2}) gcd(Ax2+By1,Ax2+By1+1,...,Ax2+By2)

    根据差分,转换为

    g c d ( A x 1 + B y 1 , B y 1 + 1 − B y 1 , . . . , B y 2 − B y 2 − 1 ) gcd(A_{x_1} + B_{y_1}, B_{y_1+1} - B_{y_1},..., B_{y_2} - B_{y_2-1}) gcd(Ax1+By1,By1+1By1,...,By2By21)

    g c d ( A x 1 + 1 + B y 1 , B y 1 + 1 − B y 1 , . . . , B y 2 − B y 2 − 1 ) gcd(A_{x_1 + 1} + B_{y_1}, B_{y_1+1} - B_{y_1},..., B_{y_2} - B_{y_2-1}) gcd(Ax1+1+By1,By1+1By1,...,By2By21)

    g c d ( A x 2 + B y 1 , B y 1 + 1 − B y 1 , . . . , B y 2 − B y 2 − 1 ) gcd(A_{x_2} + B_{y_1}, B_{y_1+1} - B_{y_1},..., B_{y_2} - B_{y_2-1}) gcd(Ax2+By1,By1+1By1,...,By2By21)

    我们会发现除了第一列以外,其他列的值一样,所以我们可以直接求出后面的gcd。
    而第一列的gcd也可以快速根据step1维护。

    step3:

    板子的gcd可能会因为负数wa

    AC

    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #define For(i,x,y) for(int i = (x); i <= (y); i ++ )
    #define fori(i,x,y) for(int i = (x); i < (y); i ++ )
    #define sz(a) (int)a.size()
    #define ALL(a) a.begin(), a.end()
    #define mst(x,a) memset(x,a,sizeof(x))
    #define pb push_back
    #define eb emplace_back
    #define mp make_pair
    #define fi first
    #define se second
    #define db double
    #define endl '\n' 
    #define debug(a) cout << #a << ": " << a << endl
    using namespace std;
    typedef long long LL;
    typedef long long ll;
    typedef unsigned long long ULL;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    const int inf = 0x3f3f3f3f;
    const int mod = 1e9+7;
    typedef pair<int,int>pa;
    typedef pair<ll,ll>pai;
    typedef pair<db,db> pdd;
    const db eps = 1e-6;
    const db pi = acos(-1.0);
    
    template<typename T1, typename T2> void ckmin(T1 &a, T2 b) { if (a > b) a = b; }
    template<typename T1, typename T2> void ckmax(T1 &a, T2 b) { if (a < b) a = b; }
    int read() {
        int x = 0, f = 0; char ch = getchar();
        while (!isdigit(ch)) f |= ch == '-', ch = getchar();
        while (isdigit(ch)) x = 10 * x + ch - '0', ch = getchar();
        return f ? -x : x;
    }
    template<typename T> void print(T x) {
        if (x < 0) putchar('-'), x = -x;
        if (x >= 10) print(x / 10);
        putchar(x % 10 + '0');
    }
    template<typename T> void print(T x, char let) {
        print(x), putchar(let);
    }
    template<class T> bool uin(T &a, T b) { return a > b ? (a = b, true) : false; }
    template<class T> bool uax(T &a, T b) { return a < b ? (a = b, true) : false; }
    
    const int maxn = 200000 + 6;
    const int LOGMX = 20;
    int gcd(int a, int b) {
        if(b == 0) return a;
        return gcd(b,a%b);
    }
    int a[maxn], b[maxn];
    int c[maxn][LOGMX], d[maxn][LOGMX];
    int logn[maxn];
    void init(){
        for(int i = 2; i < maxn; i ++ ) logn[i] = logn[i/2] + 1;
    }
    int query1(int l, int r) {
        if(l > r) return 0;
        int s = logn[r-l+1];
        return std::gcd(c[l][s],c[r-(1<<s)+1][s]);
    }
    int query2(int l, int r) {
        if(l > r) return 0;
        int s = logn[r-l+1];
        return std::gcd(d[l][s],d[r-(1<<s)+1][s]);
    }
    int main() {
        ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
        // gcd(a1+b1,a1+b2,a1+b3);
        // gcd(a1+b1,b2-b1,b3-b1)
        init();
        int n, q;
        cin >> n >> q;
        for(int i = 1; i <= n; i ++ ) cin >> a[i];
        for(int i = 1; i <= n; i ++ ) cin >> b[i];
    
    
        for(int i = 1; i < n; i ++ ) {
            c[i][0] = a[i+1] - a[i];
            d[i][0] = b[i+1] - b[i];
        }
    
        //rmq init
        for(int j = 1; j < LOGMX; j ++ ) {
            for(int i = 1; i + (1<<j) - 1 < n; i ++) {
                c[i][j] = std::gcd(c[i][j-1], c[i+(1<<(j-1))][j-1]);
                d[i][j] = std::gcd(d[i][j-1], d[i+(1<<(j-1))][j-1]);
            }
        }
    
        for(int i = 1; i <= q; i ++ ) {
            int x1,y1,x2,y2;
            cin>> x1 >> x2 >> y1 >> y2;
            cout << std::gcd(a[x1] + b[y1], gcd(query1(x1,x2-1), query2(y1,y2-1))) << endl;
        }
    
        return 0;
    }
    //负数的gcd,和推导
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
  • 相关阅读:
    虹科 | 解决方案 | 汽车示波器 远程诊断方案
    【C/C++】递归算法
    hexo博客使用docker自动化部署阿里云
    漏洞复现-Apache Druid 任意文件读取 _(CVE-2021-36749)
    无源DWDM与有源DWDM:两种系统在5G时代的作用与挑战
    建造者模式
    蓝桥杯2024年第十五届省赛真题-小球反弹
    EasyRecovery2024破解版激活码
    hadoop MapReduce运营商案例关于用户基站停留数据统计
    Web前端:JavaScript-->流程控制语句*笔记
  • 原文地址:https://blog.csdn.net/qq_45377553/article/details/126670961