博客
关于我
P3899 [湖南集训]谈笑风生 主席树解决二维数点
阅读量:275 次
发布时间:2019-03-01

本文共 2592 字,大约阅读时间需要 8 分钟。

??????????????

??

????????????a?b????????????c??????????????????????????????????????????????

  • ??????b???a??????????????a??????????[depth[a]+1, depth[a]+k]????????se[i]-1??????k?
  • ??????a???b??????????????b??????????[depth[b]+1, depth[b]+k]????????se[i]-1??????k?
  • ??

    ????????????????????????????????????????????????Heavy-Light Decomposition, HLD???????????????????????????????DFS?????????????????????????????????????????????????

    ???????

  • ????????????????????????????????
  • ???????????????????????????????
  • ???????

    ???????

    • ??????????????????????????????
    • ??????????????DFS????????????????
    • ?????????????????????????????

    ?????????

    • ???????DFS??????????
    • ??????????????????????

    ?????????

    ???????????????????????????O(log n)?

    ??

    ????????

    root   /   \  a     b
    • ?????????[2, 3]???k=2?
      • ?????[depth[a]+1, depth[a]+k] = [2, 4]
      • ?????depth[a]?depth[b]??2?3?

    ????

    #include 
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    using namespace std;typedef long long LL;typedef unsigned long long ULL;typedef pair
    PII;const int N = 1000010;const int mod = 1e9 + 7;const double eps = 1e-6;int root[N], dfn[N], se[N], depth[N];vector
    v[N];int idx = 1;struct Node { int l, r; LL sum;};void dfs1(int u, int fa) { se[u] = 1; dfn[u] = ++idx; depth[u] = depth[fa] + 1; for (int x : v[u]) { if (x != fa) { dfs1(x, u); se[u] += se[x]; } }}void dfs2(int u, int fa) { insert(root[dfn[u] - 1], root[dfn[u]], 1, N, depth[u], se[u] - 1); for (int x : v[u]) { if (x != fa) { dfs2(x, u); } }}void insert(int p, int &q, int l, int r, int pos, int x) { q = ++idx; tr[q] = tr[p]; tr[q].sum += x; if (l == r) return; int mid = (l + r) >> 1; if (pos <= mid) { insert(tr[p].l, tr[q].l, l, mid, pos, x); } else { insert(tr[p].r, tr[q].r, mid + 1, r, pos, x); }}LL query(int p, int q, int l, int r, int ql, int qr) { if (l > ql && r <= qr) return tr[q].sum - tr[p].sum; LL ans = 0; int mid = (l + r) >> 1; if (ql <= mid) ans += query(tr[p].l, tr[q].l, l, mid, ql, qr); if (qr > mid) ans += query(tr[p].r, tr[q].r, mid + 1, r, ql, qr); return ans;}void main() { cin.sync_with_stdio(false); cin.tie(0); int n, m; for (int i = 1; i < n; ++i) { int a, b; cin >> a >> b; v[a].push_back(b); v[b].push_back(a); } dfs1(1, 0); dfs2(1, 0); while (m--) { int p, k; cin >> p >> k; LL ans = min(depth[p] - 1, k) * (se[p] - 1); ans += query(root[dfn[p]], root[dfn[p] + se[p] - 1], 1, N, depth[p] + 1, min(depth[p] + k, N)); cout << ans << endl; } return 0;}

    ??

    ???????????????????????????????????????????????????O(n log n)?????????????

    转载地址:http://xvlx.baihongyu.com/

    你可能感兴趣的文章
    Objective-C实现basic graphs基本图算法(附完整源码)
    查看>>
    Objective-C实现BCC校验计算(附完整源码)
    查看>>
    Objective-C实现bead sort珠排序算法(附完整源码)
    查看>>
    Objective-C实现BeadSort珠排序算法(附完整源码)
    查看>>
    Objective-C实现bellman ford贝尔曼福特算法(附完整源码)
    查看>>
    Objective-C实现bellman-ford贝尔曼-福特算法(附完整源码)
    查看>>
    Objective-C实现bellman-ford贝尔曼-福特算法(附完整源码)
    查看>>
    Objective-C实现BellmanFord贝尔曼-福特算法(附完整源码)
    查看>>
    Objective-C实现bezier curve贝塞尔曲线算法(附完整源码)
    查看>>
    Objective-C实现bfs 最短路径算法(附完整源码)
    查看>>
    Objective-C实现BF算法 (附完整源码)
    查看>>
    Objective-C实现Bilateral Filter双边滤波器算法(附完整源码)
    查看>>
    Objective-C实现binary exponentiation二进制幂运算算法(附完整源码)
    查看>>
    Objective-C实现binary search二分查找算法(附完整源码)
    查看>>
    Objective-C实现binary tree mirror二叉树镜像算法(附完整源码)
    查看>>
    Objective-C实现binary tree traversal二叉树遍历算法(附完整源码)
    查看>>
    Objective-C实现BinarySearchTreeNode树算法(附完整源码)
    查看>>
    Objective-C实现binomial coefficient二项式系数算法(附完整源码)
    查看>>
    Objective-C实现bisection二分法算法(附完整源码)
    查看>>
    Objective-C实现bisection二等分算法(附完整源码)
    查看>>