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

    你可能感兴趣的文章
    PHP实现微信公众号网页授权
    查看>>
    PHP实现微信小程序推送消息至公众号
    查看>>
    php实现根据身份证获取年龄
    查看>>
    PHP实现的MongoDB数据增删改查
    查看>>
    RabbitMQ连接报错(1)—— None of the specified endpoints were reachable
    查看>>
    php实现逆转数组
    查看>>
    PHP实现页面静态化、纯静态化及伪静态化
    查看>>
    PHP对表单提交特殊字符的过滤和处理
    查看>>
    php对象引用和析构函数的关系
    查看>>
    RabbitMQ HTTP 认证后端项目常见问题解决方案
    查看>>
    PHP将图片转换成base64格式(优缺点)
    查看>>
    php将多个值的数组去除重复元素
    查看>>
    php局域网上传文件_PHP如何通过CURL上传文件
    查看>>
    PHP工具插件大全
    查看>>
    php布尔值的++
    查看>>
    PHP常量、变量作用域详解(一)
    查看>>
    PHP应用目录结构设计
    查看>>
    PHP应用程序连接MSQL数据库Demo(附crud程序)
    查看>>
    PHP开发api接口安全验证
    查看>>
    PHP开发规范PSR
    查看>>