• bzoj 1095: [ZJOI2007]Hide 捉迷藏


    bzoj 1095: [ZJOI2007]Hide 捉迷藏

    Description

    捉迷藏 Jiajia和Wind是一对恩爱的夫妻,并且他们有很多孩子。某天,Jiajia、Wind和孩子们决定在家里玩捉迷藏游戏。他们的家很大且构造很奇特,由N个屋子和N-1条双向走廊组成,这N-1条走廊的分布使得任意两个屋子都互相可达。游戏是这样进行的,孩子们负责躲藏,Jiajia负责找,而Wind负责操纵这N个屋子的灯。在起初的时候,所有的灯都没有被打开。每一次,孩子们只会躲藏在没有开灯的房间中,但是为了增加刺激性,孩子们会要求打开某个房间的电灯或者关闭某个房间的电灯。为了评估某一次游戏的复杂性,Jiajia希望知道可能的最远的两个孩子的距离(即最远的两个关灯房间的距离)。 我们将以如下形式定义每一种操作: C(hange) i 改变第i个房间的照明状态,若原来打开,则关闭;若原来关闭,则打开。 G(ame) 开始一次游戏,查询最远的两个关灯房间的距离。

    Input

    第一行包含一个整数N,表示房间的个数,房间将被编号为1,2,3…N的整数。接下来N-1行每行两个整数a, b,
    表示房间a与房间b之间有一条走廊相连。接下来一行包含一个整数Q,表示操作次数。接着Q行,每行一个操作,如
    上文所示。

    Output

    对于每一个操作Game,输出一个非负整数到hide.out,表示最远的两个关灯房间的距离。若只有一个房间是关
    着灯的,输出0;若所有房间的灯都开着,输出-1。

    Sample Input

    8

    1 2

    2 3

    3 4

    3 5

    3 6

    6 7

    6 8

    7

    G

    C 1

    G

    C 2

    G

    C 1

    G

    Sample Output

    4

    3

    3

    4

    HINT

    对于(100\%)的数据,(N le 100000, M le 500000)

    上次罗老师讲了这道题,今天才写这道题。

    此题我们首先要进行树分治。

    先通过树分治的重心建一棵树,每个节点维护两个堆,一个维护子树到节点的距离,另一个维护其子树的第一个堆的堆顶。

    我们再利用一个全局堆维护答案。

    #include <queue>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
     
    const int N = 100013;
     
    class heap {
    protected:
        priority_queue < int > A, B;
    public:
        void push(const int &x) {
            A.push(x);
        }
        void erase(const int &x) {
            B.push(x);
        }
        void pop() {
            while (!B.empty() && !(A.top() ^ B.top()))
                A.pop(), B.pop();
            A.pop();
        }
        int top() {
            while (!B.empty() && !(A.top() ^ B.top()))
                A.pop(), B.pop();
            return A.empty() ? -0x3f3f3f3f : A.top();
        }
        int size() const {
            return A.size() - B.size();
        }
        bool empty() const {
            return !(A.size() ^ B.size());
        }
        int tps() {
            if (size() < 2) return -0x3f3f3f3f;
            int t1, t2;
            while (!B.empty() && !(A.top() ^ B.top()))
                A.pop(), B.pop();
            t1 = A.top(); A.pop();
            while (!B.empty() && !(A.top() ^ B.top()))
                A.pop(), B.pop();
            t2 = A.top(); A.push(t1);
            return t1 + t2;
        }
    }GlobleHeap, FirstHeap[N], SecondHeap[N];
     
    struct edge {
        int t;
        edge *n;
    } me[N << 1 | 1], *ce = me, *g[N];
     
    inline void adde(const int &a, const int &b) {
        ce->t = b, ce->n = g[a], g[a] = ce++;
    }
     
    int deep[N], fa[20][N], dis[20][N], size[N], f[N], totsize, rt, tot_off;
    bool vis[N], on[N];
     
    inline void cmax(int &a, const int &b) {
        if (a < b) a = b;
    }
     
    void grt(int u, int father) {
        int v;
        size[u] = 1, f[u] = 0;
        for (edge *it = g[u]; it; it = it->n) {
            v = it->t;
            if (vis[v] || (v == father)) continue;
            grt(v, u);
            size[u] += size[v];
            cmax(f[u], size[v]);
        }
        cmax(f[u], totsize - size[u]);
        if (f[u] < f[rt]) rt = u;
    }
     
    void dfs(int u, const int &anc, int father, int dep) {
        int v;
        for (edge *it = g[u]; it; it = it->n) {
            v = it->t;
            if (vis[v] || (v == father)) continue;
            fa[++deep[v]][v] = anc;
            dis[deep[v]][v] = dep;
            dfs(v, anc, u, dep + 1);
        }
    }
     
    void build(int u) {
        int v, all = totsize;
        vis[u] = true;
        dfs(u, u, 0, 1);
        for (edge *it = g[u]; it; it = it->n) {
            if (vis[v = it->t]) continue;
            if (size[u] < size[v])
                size[v] = all - size[u];
            totsize = size[v];
            rt = 0;
            grt(v, u);
            build(rt);
        }
    }
     
    inline void turn_off(const int &u) {
        static int t, i, pre;
        SecondHeap[u].push(0);
        if (SecondHeap[u].size() == 2)
            GlobleHeap.push(SecondHeap[u].top());
        for (i = deep[u]; i > 1; --i)
            if (FirstHeap[fa[i][u]].empty()) {
                FirstHeap[fa[i][u]].push(dis[i - 1][u]);
                pre = SecondHeap[fa[i - 1][u]].tps();
                SecondHeap[fa[i - 1][u]].push(dis[i - 1][u]);
                if (pre > 0) {
                    if (pre ^ (t = SecondHeap[fa[i - 1][u]].tps())) {
                        GlobleHeap.erase(pre);
                        GlobleHeap.push(t);
                    }
                } else if ((t = SecondHeap[fa[i - 1][u]].tps()) > 0)
                           GlobleHeap.push(t);
            } else {
                t = FirstHeap[fa[i][u]].top();
                FirstHeap[fa[i][u]].push(dis[i - 1][u]);
                if (t < dis[i - 1][u]) {
                    pre = SecondHeap[fa[i - 1][u]].tps();
                    SecondHeap[fa[i - 1][u]].erase(t);
                    SecondHeap[fa[i - 1][u]].push(dis[i - 1][u]);
                    if (pre > 0 && (pre ^ (t = SecondHeap[fa[i - 1][u]].tps()))) {
                        GlobleHeap.erase(pre);
                        GlobleHeap.push(t);
                    }
                }
            }
    }
     
    inline void turn_on(const int &u) {
        SecondHeap[u].erase(0);
        if (SecondHeap[u].size() == 1)
            GlobleHeap.erase(SecondHeap[u].top());
        for (int t, pre, i = deep[u]; i > 1; --i) {
            FirstHeap[fa[i][u]].erase(dis[i - 1][u]);
            if (FirstHeap[fa[i][u]].top() < dis[i - 1][u]) {
                pre = SecondHeap[fa[i - 1][u]].tps();
                SecondHeap[fa[i - 1][u]].erase(dis[i - 1][u]);
                if (!FirstHeap[fa[i][u]].empty())
                    SecondHeap[fa[i - 1][u]].push(FirstHeap[fa[i][u]].top());
                if (pre > 0 && (pre ^ (t = SecondHeap[fa[i - 1][u]].tps()))) {
                    GlobleHeap.erase(pre);
                    if (SecondHeap[fa[i - 1][u]].size() > 1)
                        GlobleHeap.push(t);
                }
            }
        }
    }
     
    inline void Switch(const int &u) {
        if (on[u]) turn_off(u);
        else turn_on(u);
        on[u] ^= 1;
        if (on[u]) --tot_off;
        else ++tot_off;
    }
     
    int main() {
        //freopen("1095.in", "r", stdin);
        int n, m, u, v;
        char ops[4];
        scanf("%d", &n);
        for (m = 1; m < n; ++m) {
            scanf("%d%d", &u, &v);
            adde(u, v), adde(v, u);
        }
        f[0] = 0x3f3f3f3f;
        totsize = tot_off = n;
        grt(1, 0);
        build(rt);
        for (m = 1; m <= n; ++m)
            fa[++deep[m]][m] = m, turn_off(m);
        scanf("%d", &m);
        while (m--) {
            scanf("%s", ops);
            if (*ops == 'G') {
                if (!tot_off)puts("-1");
                else printf("%d
    ", max(GlobleHeap.top(), 0));
            } else {
                scanf("%d", &u);
                Switch(u);
            }
        }
        return 0;
    }
    
  • 相关阅读:
    WRF WPS预处理
    CVS安装
    Linux窗口最小化消失,任务栏上无法找到的解决方法
    NCARG安装配置出现error while loading shared libraries: libg2c.so.0问题额解决办法
    Netcdf安装
    Embedding R-generated Interactive HTML pages in MS PowerPoint(转)
    The leaflet package for online mapping in R(转)
    Some 3D Graphics (rgl) for Classification with Splines and Logistic Regression (from The Elements of Statistical Learning)(转)
    What does a Bayes factor feel like?(转)
    Weka算法介绍
  • 原文地址:https://www.cnblogs.com/cycleke/p/6322597.html
Copyright © 2020-2023  润新知