zoukankan      html  css  js  c++  java
  • bzoj3653: 谈笑风生

    设sz为子树大小,根的深度为1.

    显然答案为min(dep[p] - 1, k) * (sz[p] - 1) + sigma(sz[u], u在p的子树中,dep[u] - dep[p] <= k)

    对于加号右边,对两个区间的限制条件询问信息,可以考虑可持久化线段树,但不同版本间的信息必须满足区间减法。

    具体是dfs序在外面还是深度在外面无所谓(深度最大值<=n,所以用深度常数会小?)

      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<algorithm>
      4 #include<iostream>
      5 #include<cstring>
      6 #include<string>
      7 
      8 using namespace std;
      9 
     10 void setIO(const string& a) {
     11     freopen((a + ".in").c_str(), "r", stdin);
     12     freopen((a + ".out").c_str(), "w", stdout);
     13 }
     14 
     15 typedef long long LL;
     16 const int N = 300000 + 10, logn = 20;
     17 
     18 struct Node *pis, *null;
     19 
     20 struct Node {
     21     LL s;
     22     Node* ch[2];
     23     
     24     Node(LL s = 0) : s(s) {
     25         ch[0] = ch[1] = null;
     26     }
     27     
     28     void *operator new(size_t) {
     29         return pis++;
     30     }
     31 }*root[N], pool[N * logn];
     32 
     33 #define mid (l + ((r - l) >> 1))
     34 #define ls x->ch[0], y->ch[0], l, mid
     35 #define rs x->ch[1], y->ch[1], mid + 1, r
     36 
     37 void build(Node*& x, Node *y, int l, int r, int key, int val) {
     38     x = new Node(*y), x->s += val;
     39     if(l == r) return;
     40     if(key <= mid) build(ls, key, val); else build(rs, key, val);
     41 }
     42 
     43 LL query(Node *x, Node *y, int l, int r, int lft, int rgt) {
     44     if(lft <= l && r <= rgt) return y->s - x->s;
     45     LL res = 0;
     46     if(lft <= mid) res += query(ls, lft, rgt);
     47     if(mid < rgt) res += query(rs, lft, rgt);
     48     return res;
     49 }
     50 
     51 #undef mid
     52 #undef ls
     53 #undef rs
     54 
     55 int dfs_seq[N], pre[N], end[N], sz[N], dep[N], dfs_clk, max_dep;
     56 
     57 #include<vector>
     58 vector<int> G[N];
     59 void AddEdge(int u, int v) {
     60     G[u].push_back(v);
     61     G[v].push_back(u);
     62 }
     63 
     64 void dfs(int u) {
     65     max_dep = max(max_dep, dep[u]);
     66     dfs_seq[++dfs_clk] = u;
     67     pre[u] = dfs_clk;
     68     sz[u] = 1;
     69     for(unsigned i = 0; i < G[u].size(); ++i) {
     70         int v = G[u][i];
     71         if(dep[v]) continue;
     72         dep[v] = dep[u] + 1;
     73         dfs(v);
     74         sz[u] += sz[v];
     75     }
     76     end[u] = dfs_clk;
     77 }
     78 
     79 int main() {
     80 #ifdef DEBUG
     81     freopen("in.txt", "r", stdin);
     82     freopen("out.txt", "w", stdout);
     83 #endif
     84     
     85     pis = pool;
     86     int n, m;
     87     scanf("%d%d", &n, &m);
     88     for(int i = 1; i < n; i++) {
     89         int u, v;
     90         scanf("%d%d", &u, &v);
     91         AddEdge(u, v);
     92     }
     93     
     94     dep[1] = 1, dfs(1);
     95     
     96 //    cerr << max_dep << endl;
     97     
     98     root[0] = null = new Node(0);
     99     null->ch[0] = null->ch[1] = null;
    100     
    101     for(int i = 1; i <= n; i++) {
    102         build(root[i], root[i - 1], 1, max_dep, dep[dfs_seq[i]], sz[dfs_seq[i]] - 1);
    103     }
    104     
    105     for(int i = 1; i <= m; i++) {
    106         int p, k;
    107         scanf("%d%d", &p, &k);
    108         LL res = (LL) min(dep[p] - 1, k) * (sz[p] - 1);
    109         res += query(root[pre[p]], root[end[p]], 1, max_dep, dep[p] + 1, min(dep[p] + k, max_dep));
    110         printf("%lld
    ", res);
    111     }
    112     
    113     return 0;
    114 }
  • 相关阅读:
    C++ 虚函数表解析(转载)
    javaWeb中的/路径问题
    java创建多线程(转载)
    JSP中pageEncoding和charset区别,中文乱码解决方案(转载)
    Class.forName()的作用与使用总结(转载)
    Java内存模型
    java-锁膨胀的过程
    java对象头信息和三种锁的性能对比
    并发容器
    synchronized和volatile以及ReentrantLock
  • 原文地址:https://www.cnblogs.com/showson/p/5006640.html
Copyright © 2011-2022 走看看