[补档计划] 树2 - 树上倍增

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[补档计划] 树2 - 树上倍增相关的知识,希望对你有一定的参考价值。

[SCOI2016] 萌萌哒

题意

  求有多少个无前导零的 $N(N\le 10^5)$ 位数 $A$ , 满足 $M(M\le 10^5)$ 个限制条件 $L~R~X~Y$ : $A[L+i] = A[X+i]$ .

分析

  区间的信息就先对 ST 表用并查集, 然后下传.

实现

技术分享
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cctype>
#include <cmath>

#define F(i, a, b) for (register int i = (a); i <= (b); i++)
#define D(i, a, b) for (register int i = (a); i >= (b); i--)

const int L = (int)1e9+7;

int n, m;
int f[2000000], c;
int cnt, res;

inline int rd(void) {
    int f = 1; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == -) f = -1;
    int x = 0; for (; isdigit(c); c = getchar()) x = x * 10 + c - 0; return x * f;
}

inline int id(int i, int j) { return i * n + j; }
inline int Find(int x) { return f[x] == x ? x : f[x] = Find(f[x]); }
inline void Union(int x, int y) { f[Find(x)] = Find(y); }

int main(void) {
    #ifndef ONLINE_JUDGE
        freopen("xsy2412.in", "r", stdin);
        freopen("xsy2412.out", "w", stdout);
    #endif

    n = rd(), m = rd(), c = (int)log2(n);
    for (int i = 1, up = id(c, n); i <= up; i++) f[i] = i;
    F(i, 1, m) {
        int l = rd(), r = rd(), x = rd(), y = rd();
        for (int j = c; j >= 0 && r >= l; j--)
            if (r - (1<<j) + 1 >= l) {
                Union(id(j, r), id(j, y));
                r -= (1<<j), y -= (1<<j);
            }
    }

    D(i, c, 1)
        F(j, 1<<i, n) {
            int k = f[id(i, j)] - i*n;
            if (j != k) {
                Union(id(i-1, j), id(i-1, k));
                Union(id(i-1, j - (1<<(i-1))), id(i-1, k - (1<<(i-1))));
            }
        }

    F(i, 1, n) cnt += (i == Find(i));
    res = 9; F(i, 2, cnt) res = 1LL * res * 10 % L; printf("%d\n", res);

    return 0;
}
View Code

 

以上是关于[补档计划] 树2 - 树上倍增的主要内容,如果未能解决你的问题,请参考以下文章

树上倍增求LCA

[补档计划] 树6 - 莫队算法

BZOJ 3551[ONTAK2010] Peaks加强版 Kruskal重构树+树上倍增+主席树

洛谷 P2680 [NOIP2015 提高组] 运输计划(二分,树上查分,树上倍增,LCA)

gym 101081F Auction of Services 最小生成树扩展lca树上倍增

bzoj3732 -- 最小生成树+倍增