zoukankan      html  css  js  c++  java
  • $bzoj4569$

    $st表+并查集$

    $考虑暴力方法:我们每次将对应相等的位置用并查集连起来,那么最终答案就是9*10^{连通块个数-1}$

    $很明显上面这个办法过不去,问题在于重复次数太多了,如果一个区间已经对应相等了就不用再次连,用st表优化这个过程$

    $每次向st表一样递归连接,分成log层,每层维护frac{n}{logn}个并查集,代表区间,那么我们加入记忆化的思想,如果对应区间已经联通就返回,这个就是用并查集完成,否则继续递归进行这个过程。其实这里就是运用了记忆化的思想$

    $那么很明显每层穿起来所有区间需要区间个数-1次,那么一共有nlogn个区间,复杂度也就是nlogn了$

    $所以看见这种题就要考虑用一些方式记忆化从而降低复杂度$

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 1e5 + 5, P = 1e9 + 7;
    int n, m;
    int fa[18][N], Log[N];
    int find(int p, int x) {
        return x == fa[p][x] ? x : fa[p][x] = find(p, fa[p][x]);
    }
    void merge(int k, int a, int b) {
        int x = find(k, a), y = find(k, b);
        if(x == y) {
            return;
        }
        fa[k][x] = y;
        if(!k) {
            return;
        }
        merge(k - 1, a, b);
        merge(k - 1, a + (1 << k - 1), b + (1 << k - 1));
    }
    int main() {
        scanf("%d%d", &n, &m);
        if(n == 1) {
            puts("10");
            return 0;
        }
        for(int j = 0; j <= 17; ++j) {
            for(int i = 1; i + (1 << j) - 1 <= n; ++i) {
                fa[j][i] = i;       
            }
        }
        for(int i = 2; i <= n; ++i) {
            Log[i] = Log[i >> 1] + 1;
        }
        while(m--) {
            int a, b, c, d;
            scanf("%d%d%d%d", &a, &b, &c, &d);
            int t = Log[b - a + 1];
            merge(t, a, c);
            merge(t, b - (1 << t) + 1, d - (1 << t) + 1);
        }
        long long ans = 9, f = 0;
        for(int i = 1; i <= n; ++i) {
            if(find(0, i) == i) {
                if(f) {
                    ans = ans * 10 % P;
                } else {
                    f = 1;
                }
            }
        }
        printf("%lld
    ", ans);
        return 0;
    }
    View Code
  • 相关阅读:
    找水王
    环状二维数组最大子数组和
    用户模板
    课堂作业-电梯调度
    书店折扣问题
    《软件工程》读后感
    首尾相连的二维数组最大子数组求和
    梦断代码读后感(二)
    返回一个整数数组中最大子数组的和之测试
    首尾相连的一位数组最大子数组和
  • 原文地址:https://www.cnblogs.com/19992147orz/p/8372649.html
Copyright © 2011-2022 走看看