zoukankan      html  css  js  c++  java
  • bzoj4154

    kdtree

    转换一下,看成点,第一位dfs序,第二维深度,那么满足在子树内dfs序限制,然后kdtree上打标记就行了。

     
    #include<bits/stdc++.h>
    using namespace std;
    const int N = 1e5 + 5, mod = 1e9 + 7;
    int rd()
    {
        int x = 0, f = 1; char c = getchar();
        while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar(); }
        while(c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
        return x * f;
    }
    int n, c, q, root, d, dfs_clock;
    int dep[N], in[N], out[N];
    vector<int> G[N];
    struct data {
        int lc, rc, c, tag, p[2], mx[2], mn[2];
        bool friend operator < (const data &a, const data &b) {
            return a.p[d] == b.p[d] ? a.p[d ^ 1] < b.p[d ^ 1] : a.p[d] < b.p[d];
        }
    } a[N];
    void update(int x)
    {
        int lc = a[x].lc, rc = a[x].rc;
        for(int i = 0; i < 2; ++i) 
        {
            a[x].mn[i] = min(a[x].p[i], min(a[lc].mn[i], a[rc].mn[i]));
            a[x].mx[i] = max(a[x].p[i], max(a[lc].mx[i], a[rc].mx[i]));
        }
    }
    int build(int l, int r, int D)
    {
        if(l > r) return 0;
        d = D;
        int mid = (l + r) >> 1;
        nth_element(a + l, a + mid, a + r + 1);
        a[mid].lc = build(l, mid - 1, D ^ 1);
        a[mid].rc = build(mid + 1, r, D ^ 1);
        a[mid].c = 1;
        a[mid].tag = 0;
        update(mid);
        return mid;
    }
    void pushdown(int x)
    {
        if(!a[x].tag) return;
        int lc = a[x].lc, rc = a[x].rc;
        if(lc) a[lc].tag = a[lc].c = a[x].tag;
        if(rc) a[rc].tag = a[rc].c = a[x].tag;
        a[x].tag = 0;
    }
    bool In(int x1, int y1, int x2, int y2, int X1, int Y1, int X2, int Y2)
    {
        return X1 >= x1 && Y1 >= y1 && X2 <= x2 && Y2 <= y2; 
    }
    bool Out(int x1, int y1, int x2, int y2, int X1, int Y1, int X2, int Y2)
    {
        return x1 > X2 || x2 < X1 || y1 > Y2 || y2 < Y1;
    }
    int query(int k, int x, int y)
    {
        if(!k || Out(x, y, x, y, a[k].mn[0], a[k].mn[1], a[k].mx[0], a[k].mx[1])) return 0;
        pushdown(k);
        if(x == a[k].p[0] && y == a[k].p[1]) return a[k].c;
        return query(a[k].lc, x, y) + query(a[k].rc, x, y);
    }
    void modify(int k, int x1, int y1, int x2, int y2, int c)
    {
        if(!k || Out(x1, y1, x2, y2, a[k].mn[0], a[k].mn[1], a[k].mx[0], a[k].mx[1])) return;
        pushdown(k);
        if(In(x1, y1, x2, y2, a[k].mn[0], a[k].mn[1], a[k].mx[0], a[k].mx[1])) 
        {
            a[k].tag = a[k].c = c;
            return; 
        }
        if(In(x1, y1, x2, y2, a[k].p[0], a[k].p[1], a[k].p[0], a[k].p[1])) a[k].c = c;
        modify(a[k].lc, x1, y1, x2, y2, c);
        modify(a[k].rc, x1, y1, x2, y2, c);
    }
    void dfs(int u)
    {
        a[u].p[0] = a[u].mn[0] = a[u].mx[0] = dep[u];
        a[u].p[1] = a[u].mn[1] = a[u].mx[1] = in[u] = ++dfs_clock;
        a[u].lc = a[u].rc = 0;
        for(int i = 0; i < G[u].size(); ++i) 
        {
            dep[G[u][i]] = dep[u] + 1;
            dfs(G[u][i]);
        }
        out[u] = dfs_clock;
    }
    int main()
    {
        for(int i = 0; i < 2; ++i)
            a[0].mn[i] = 1e9,
            a[0].mx[i] = -1e9;
        int T = rd();
        while(T--)
        {
            long long ans = 0;
            n = rd();
            c = rd();
            q = rd();
            for(int i = 1; i <= n; ++i) G[i].clear();
            for(int i = 2; i <= n; ++i)
            {
                int fa = rd();
                G[fa].push_back(i);
            }
            dep[1] = 1;
            dfs(1);
            root = build(1, n, 0);
            for(long long i = 1; i <= q; ++i)
            {
                int a = rd(), l = rd(), c = rd();
                int dd = query(root, in[a], dep[a]);
                if(c == 0) ans = (ans + (long long)query(root, dep[a], in[a]) * i) % mod;
                if(c > 0) modify(root, dep[a], in[a], min(dep[a] + l, n), out[a], c);             
            }
            printf("%lld
    ", ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    [LeetCode]Sliding Window Maximum
    判断两根线段是否相交
    求幂,我居然又没做出来
    C++集合运算函数总结 & 需要有序集合的操作
    effective stl读书笔记 & stl里面提供的算法 & emplace & ostream_iterator
    利用位操作的几道题目
    C++的new_handler
    TCP的可靠性 窗口滑动 拥塞控制
    关于高性能网络编程的一些知识
    三种连接 & DOS & SYNFLOOD & 防御
  • 原文地址:https://www.cnblogs.com/19992147orz/p/7882109.html
Copyright © 2011-2022 走看看