zoukankan      html  css  js  c++  java
  • 【LG3247】[HNOI2016]最小公倍数

    【LG3247】[HNOI2016]最小公倍数

    题面

    洛谷

    题解

    50pts

    因为拼凑起来的部分分比较多,所以就放一起了。

    以下设询问的(a,b)(A,B)

    复杂度(O(nm))的:将所有(aleq A,bleq B)的边两端,用并查集并起来,再看一看等于(A,B)的是否有端点在集合中即可。

    一条链的:拿线段树之类的数据结构维护一下即可。

    (a)等于(0)的:将边的和询问按照(b)排序,用(two;pointers)扫一遍丢到并查集中即可。

    100pts

    首先考虑暴力,每次询问暴力求出所有(leq a, leq b)的边,然后判断判断两点是否联通,并且联通块内最大值是否合法就可以了。

    接下来的(A)(B)还是是询问的(a, b)

    将所有的边按照(a)排序并分块,将所有的询问按照(b)排序。

    设第(i)块的区间是([l_i, r_i]),找出所有的(A in [a_{l_i}, a_{r_i}))的询问,然后一个一个处理。

    对于第(j)个询问,有两种边可以产生贡献,一种是在([1, i))(b leq B_j)的边,这种边可以用一个指针维护。

    还有一种是在第(i)块的(a leq A_j)(b leq B_j)的边,这种边最多只有块的大小条,可以暴力加边。

    因为每一次加了第二种边之后要撤销这些操作,所以要写一个支持撤销的并查集。

    然后,当块的大小为(sqrt{mlog_2n})时据说最快。

    (感谢(xgzc)友情提供)

    代码

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    using namespace std;
    inline int gi() {
        register int data = 0, w = 1;
        register char ch = 0;
        while (!isdigit(ch) && ch != '-') ch = getchar();
        if (ch == '-')
            w = -1, ch = getchar();
        while (isdigit(ch)) data = 10 * data + ch - '0', ch = getchar();
        return w * data;
    }
    
    const int MAX_N = 2e5 + 5;
    struct Edge { int u, v, a, b; } e[MAX_N];
    struct Query { int u, v, a, b, id; } q[MAX_N], p[MAX_N];
    struct Node { int u, v, a, b, s; } stk[MAX_N];
    bool cmp1(const Edge &l, const Edge &r) { return l.a == r.a ? l.b < r.b : l.a < r.a; } 
    bool cmp2(const Edge &l, const Edge &r) { return l.b == r.b ? l.a < r.a : l.b < r.b; } 
    bool cmp3(const Query &l, const Query &r) { return l.b == r.b ? l.a < r.a : l.b < r.b; } 
    int N, M, Q, top, ans[MAX_N], fa[MAX_N], A[MAX_N], B[MAX_N], size[MAX_N];
    int getf(int x) { return fa[x] == x ? x : getf(fa[x]); }
    void merge(int x, int y, int a, int b) {
        x = getf(x), y = getf(y);
        if (size[x] > size[y]) swap(x, y);
        stk[++top] = (Node){x, y, A[y], B[y], size[y]}; 
        if (x != y)
            fa[x] = y, size[y] += size[x], A[y] = max(A[x], A[y]), B[y] = max(B[x], B[y]);
        A[y] = max(A[y], a);
        B[y] = max(B[y], b);
    }
    
    int main() {
    #ifndef ONLINE_JUDGE
        freopen("cpp.in", "r", stdin);
    #endif
        N = gi(), M = gi();
        for (int i = 1; i <= M; i++) e[i] = (Edge){gi(), gi(), gi(), gi()};
        Q = gi();
        for (int i = 1; i <= Q; i++) q[i] = (Query){gi(), gi(), gi(), gi(), i};
        sort(&e[1], &e[M + 1], cmp1);
        sort(&q[1], &q[Q + 1], cmp3);
        for (int i = 1, LEN = sqrt(M * log2(N)); i <= M; i += LEN) {
            for (int j = 1; j <= N; j++) size[fa[j] = j] = 1, A[j] = B[j] = -1; 
            int tot = 0; 
            for (int j = 1; j <= Q; j++) 
                if (e[i].a <= q[j].a && (i + LEN > M || q[j].a < e[i + LEN].a)) 
                    p[++tot] = q[j]; 
            if (!tot) continue; 
            sort(&e[1], &e[i], cmp2); 
            for (int j = 1, k = 1; j <= tot; j++) { 
                while (k < i && e[k].b <= p[j].b) merge(e[k].u, e[k].v, e[k].a, e[k].b), ++k; 
                top = 0; 
                for (int l = i; l < i + LEN && l <= M; l++) 
                    if (e[l].a <= p[j].a && e[l].b <= p[j].b) 
                        merge(e[l].u, e[l].v, e[l].a, e[l].b); 
                int x = getf(p[j].u), y = getf(p[j].v); 
                ans[p[j].id] = (x == y && A[x] == p[j].a && B[x] == p[j].b); 
                while (top) { 
                    int x = stk[top].u, y = stk[top].v; 
                    fa[x] = x; 
                    A[y] = stk[top].a, B[y] = stk[top].b, size[y] = stk[top].s; 
                    --top; 
                } 
            } 
        } 
        for (int i = 1; i <= Q; i++) puts(ans[i] ? "Yes" : "No"); 
        return 0;
    }
    
  • 相关阅读:
    NVIDIA-SMI has failed because it couldn't communicate with the NVIDIA driver. Make sure that the latest NVIDIA driver is installed and running.
    QOpenGLShaderProgram: could not create shader program
    ubuntu loading initial ramdisk 卡住
    ubuntu 下pip install sasl报错fatal error: sasl/sasl.h: No such file or directory
    ImportError: No module named managers
    python docker 多进程提供 稳定tensorflow gpu 线上服务
    侧脸生成正脸概论与精析(一)Global and Local Perception GAN
    pytorch安装 caffe2 安装:git 慢 caffe2 cannot find -lopencv_dep_cudart ,undefined reference to 'pthread_create'
    undefined symbol: PyFPE_jbuf
    Metasploit后渗透模块开发
  • 原文地址:https://www.cnblogs.com/heyujun/p/10447541.html
Copyright © 2011-2022 走看看