zoukankan      html  css  js  c++  java
  • Luogu4230 连环病原体

    Description

    link

    给一个图,有 (m) 条边,如果有一个区间的所有边构成了环,则使该区间内所有边的权值增 (1),求最后每条边的权值

    (mleq 2 imes 10^5)

    Solution

    一个比较好的结论,如果一个区间 ([l,r]) 可以构成环,那么区间([l,r ightarrow m])都可以构成环

    然后我们还有一个结论:随着(l) 的增加,(r)不减

    这个题就基本做完了……

    (LCT) 维护联通一下

    考虑每个环对边权值增加的贡献就可以了,维护需要一个二阶差分

    (l)(r) 的值增加是一个区间加,然后(r+1)(m)的增加是一个等差数列(公差 (-1)

    手推一下吧,练一练(挺常用但是难写的)

    这里博主好好练了练细节(写错一处调半天)……

    Code

    #include <bits/stdc++.h>
    using namespace std;
    #define int long long
    namespace yspm {
    inline int read() {
        int res = 0, f = 1;
        char k;
        while (!isdigit(k = getchar()))
            if (k == '-')
                f = -1;
        while (isdigit(k)) res = res * 10 + k - '0', k = getchar();
        return res * f;
    }
    const int N = 5e5 + 10;
    int f[N], c[N][2], st[N], n, ans1[N], ans2[N], ans3[N];
    bool r[N];
    inline bool notroot(int x) { return c[f[x]][0] == x || c[f[x]][1] == x; }
    inline void pushr(int x) {
        swap(c[x][0], c[x][1]);
        r[x] ^= 1;
        return;
    }
    inline void push_down(int x) {
        if (r[x]) {
            if (c[x][0])
                pushr(c[x][0]);
            if (c[x][1])
                pushr(c[x][1]);
        }
        return r[x] = 0, void();
    }
    inline void rotate(int x) {
        int y = f[x], z = f[y], k = (c[y][1] == x), w = c[x][!k];
        if (notroot(y))
            c[z][c[z][1] == y] = x;
        c[x][!k] = y;
        c[y][k] = w;
        if (w)
            f[w] = y;
        f[y] = x, f[x] = z;
        return;
    }
    inline void splay(int x) {
        int y = x, z = 0;
        st[++z] = y;
        while (notroot(y)) st[++z] = y = f[y];
        while (z) push_down(st[z--]);
        while (notroot(x)) {
            y = f[x], z = f[y];
            if (notroot(y))
                rotate((c[y][0] == x) ^ (c[z][0] == y) ? x : y);
            rotate(x);
        }
        return void();
    }
    inline void access(int x) {
        for (int y = 0; x; x = f[y = x]) splay(x), c[x][1] = y;
        return;
    }
    inline void makeroot(int x) {
        access(x);
        splay(x);
        pushr(x);
        return;
    }
    inline int findroot(int x) {
        access(x);
        splay(x);
        while (c[x][0]) push_down(x), x = c[x][0];
        splay(x);
        return x;
    }
    inline void split(int x, int y) {
        makeroot(x);
        access(y);
        splay(y);
        return;
    }
    inline void link(int x, int y) {
        makeroot(x);
        if (findroot(y) != x)
            f[x] = y;
        return;
    }
    inline void cut(int x, int y) {
        makeroot(x);
        if (findroot(y) == x & f[y] == x && !c[y][0])
            f[y] = c[x][1] = 0;
        return;
    }
    inline void add(int l, int r, int del, int d) {
        if (r < l)
            return;
        ans3[l] += del;
        ans3[l + 1] += d - del;
        ans3[r + 1] -= d * (r - l + 1) + del;
        ans3[r + 2] += d * (r - l) + del;
        return;
    }
    struct node {
        int from, to;
    } e[N];
    signed main() {
        n = read();
        for (int i = 1; i <= n; ++i) e[i].from = read(), e[i].to = read();
        for (int l = 1, r = 0; l <= n; ++l) {
            bool fl = 0;
            while (r < n) {
                ++r;
                if (findroot(e[r].from) == findroot(e[r].to)) {
                    fl = 1;
                    break;
                }
                link(e[r].from, e[r].to);
            }
            if (fl) {
                add(l, r, n - r + 1, 0);
                add(r + 1, n, n - r, -1);
                r--;
            } else
                break;
            cut(e[l].from, e[l].to);
        }
        for (int i = 1; i <= n; ++i) ans2[i] = ans2[i - 1] + ans3[i];
        for (int i = 1; i <= n; ++i) ans1[i] = ans1[i - 1] + ans2[i],printf("%lld ", ans1[i]);
        return 0;
    }
    }  // namespace yspm
    signed main() { return yspm::main(); }
    
  • 相关阅读:
    【Swift】图文混排,ios开发中在textfield或textView中插入图片
    ios开发-指纹识别
    ios开发-程序压后台后,悄悄的抓取数据~~
    setNeedDisplay和setNeedsLayout
    rangeOfString用法
    NSThread的使用
    UIActivityIndicatorView的详细使用
    iOS高斯模糊处理
    HIbernate学习笔记(一) 了解hibernate并搭建环境建立第一个hello world程序
    Hibernate4搭建Log4J日志管理(附Log4j.properties配置详解)
  • 原文地址:https://www.cnblogs.com/yspm/p/12381605.html
Copyright © 2011-2022 走看看