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\n", res);
111     }
112     
113     return 0;
114 }

 

posted @ 2015-11-30 11:11  Showson  阅读(237)  评论(0编辑  收藏  举报