博客
关于我
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/

    你可能感兴趣的文章
    poj 2112 最优挤奶方案
    查看>>
    Qt编写自定义控件12-进度仪表盘
    查看>>
    SpringBoot主启动原理在SpringApplication类《第六课》
    查看>>
    poj 2186 Popular Cows :求能被有多少点是能被所有点到达的点 tarjan O(E)
    查看>>
    POJ 2186:Popular Cows Tarjan模板题
    查看>>
    POJ 2229 Sumsets(递推,找规律)
    查看>>
    poj 2236
    查看>>
    POJ 2243 Knight Moves
    查看>>
    POJ 2262 Goldbach's Conjecture
    查看>>
    POJ 2362 Square DFS
    查看>>
    Qt笔记——解决添加Qt Designer Form Class时“allocation of incomplete type Ui::”
    查看>>
    poj 2386 Lake Counting(BFS解法)
    查看>>
    poj 2387 最短路模板题
    查看>>
    POJ 2391 多源多汇拆点最大流 +flody+二分答案
    查看>>
    POJ 2403
    查看>>
    poj 2406 还是KMP的简单应用
    查看>>
    POJ 2431 Expedition 优先队列
    查看>>
    Qt笔记——获取位置信息的相关函数
    查看>>
    POJ 2484 A Funny Game(神题!)
    查看>>
    POJ 2486 树形dp
    查看>>