zoukankan      html  css  js  c++  java
  • 【洛谷 P4116】 Qtree3 (树链剖分)

    题目链接
    树剖练手题,想复习下树剖。
    第一次提交(T)QQC
    看我
    ???
    看了数据范围的确挺恶心的,我的复杂度是(O(Mlog^2N))的,数据范围有三段

    For 1/3 of the test cases, N=5000, Q=400000.
    For 1/3 of the test cases, N=10000, Q=300000.
    For 1/3 of the test cases, N=100000, Q=100000.
    

    很极限就对了。难道是我常数太大了?那也不至于只对(3)个点吧。
    我看了一下,原来我求(size)的时候没有加上子树的(size)...这样就会剖出假的重链。
    我加上去,再交,还是(T)QQC
    看我
    ......
    原来是标记(top)的时候错了。改过来就(A)了。
    虽然有两个细节错误,但是没有别的错误,也就是说我树剖大致模板和线段树都是一次写对的。。
    话不多说。
    树剖后用线段树来维护,维护最小值,黑点的值为(dfs)序,白点的值为(INF),每次查询找到链上的最小值即为答案。
    因为从(1)(x)是一条直链,越上的点也就是越靠近(1)的点,(dfs)序一定最小。

    #include <cstdio>
    #define INF 2147483647
    #define re register
    int s; char ch;
    inline int read(){
        s = 0; ch = getchar();
        while(ch < '0' || ch > '9') ch = getchar();
        while(ch >= '0' && ch <= '9'){ s = s * 10 + ch - '0'; ch = getchar(); }
        return s;
    }
    inline int min(int a, int b){
        return a > b ? b : a;
    }
    const int MAXN = 100010;
    struct Edge{
        int next, to;
    }e[MAXN << 1];
    int head[MAXN], num, n, m, a, b, w[MAXN];
    inline void Add(int from, int to){
        e[++num].to = to; e[num].next = head[from]; head[from] = num;
        e[++num].to = from; e[num].next = head[to]; head[to] = num;
    }
    int dep[MAXN], size[MAXN], maxson[MAXN], top[MAXN], ID, dfn[MAXN], pos[MAXN], f[MAXN];
    namespace SegTree{
        #define left (now << 1)
        #define right (now << 1 | 1)
        int Min[MAXN << 2];
        inline void pushup(int now){
            Min[now] = min(Min[left], Min[right]);
        }
        void build(int now, int l, int r){
            if(l == r){ Min[now] = INF; return; }
            int mid = (l + r) >> 1;
            build(left, l, mid);
            build(right, mid + 1, r);
            pushup(now);
        }
        void update(int now, int l, int r, int x){
            if(l == r){ Min[now] = (w[pos[x]] ? x : INF); return; }
            int mid = (l + r) >> 1;
            if(x <= mid) update(left, l, mid, x);
            else update(right, mid + 1, r, x);
            pushup(now);
        }
        int query(int now, int l, int r, int wl, int wr){
            if(l > wr || r < wl) return INF;
            if(l >= wl && r <= wr) return Min[now];
            int ans = INF, mid = (l + r) >> 1;
            ans = min(ans, query(left, l, mid, wl, wr));
            ans = min(ans, query(right, mid + 1, r, wl, wr));
            return ans;
        }
    }using namespace SegTree;
    void dfs1(int u, int fa){
        size[u] = 1; f[u] = fa;
        for(re int i = head[u]; i; i = e[i].next)
           if(e[i].to != fa){
             dfs1(e[i].to, u);
             size[u] += size[e[i].to];
             if(size[e[i].to] > size[maxson[u]])
               maxson[u] = e[i].to;
           }
    }
    void dfs2(int u, int rt){
        dfn[u] = ++ID; pos[ID] = u; top[u] = rt;
        if(maxson[u]) dfs2(maxson[u], rt);
        for(re int i = head[u]; i; i = e[i].next)
           if(e[i].to != f[u] && e[i].to != maxson[u])
             dfs2(e[i].to, e[i].to);
    }
    inline int solve(int u){
        int ans = INF;
        while(top[u] != 1){
          ans = min(ans, query(1, 1, n, dfn[top[u]], dfn[u]));
          u = f[top[u]];
        }
        ans = min(ans, query(1, 1, n, dfn[1], dfn[u]));
        return ans == INF ? -1 : pos[ans];
    }
    int main(){
        n = read(); m = read();
        for(re int i = 1; i < n; ++i)
           Add(read(), read());
        dfs1(1, 0);
        dfs2(1, 1);
        build(1, 1, n);
        for(re int i = 1; i <= m; ++i){
           a = read(); b = read();
           if(!a){
             w[b] ^= 1;
             update(1, 1, n, dfn[b]);
           }
           else printf("%d
    ", solve(b));
        }
        return 0;
    }
    
    
  • 相关阅读:
    学号20145332 《信息安全系统设计基础》实验二 固件设计
    第九周学习总结
    学号20145332 《信息安全系统设计基础》期中总结
    学号20145332 《信息安全系统设计基础》实验一 开发环境的熟悉
    第七周学习总结
    第六周学习总结
    第五周学习总结
    第三周学习总结
    第二周学习总结
    第一周学习总结
  • 原文地址:https://www.cnblogs.com/Qihoo360/p/9771597.html
Copyright © 2011-2022 走看看