[BZOJ3653] laughing

Title Description

Set \ (T \) is a rooted tree, we make the following definition:

Set \ (A \) and \ (B \) of \ (T \) two different nodes.

If \ (a \) is \ (b \) ancestors, so called " \ (a \) than \ (b \) do not know clever gone."

Set \ (A \) and \ (B \) of \ (T \) in two different nodes, if \ (A \) and \ (B \) at a distance of no more than tree a given constant \ (the X-\) , then known as " \ (A \) and \ (b \) laughing."

Given a \ (n-\) rooted tree nodes \ (T \) , the number of nodes is \ (1 \) to the \ (n-\) , the root node is \ (1 \) number of nodes. you need

To answer \ (q \) th inquiry, inquiry given two integers \ (p \) and \ (k \) , asked how many ordered triples \ ((a, b, c ) \) is satisfied:

  1. \ (a, b \) and \ (C \) is $ T $ in three different points, and \ (A \) of \ (P \) number of nodes;

  2. \ (a \) and \ (b \) than the $ c $ clever do not know where to go;

  3. \ (A \) and \ (B \) laughing. Constant is given here talking in \ (K \) .

Input

The first line contains two positive integers \ (n-\) and \ (Q \) number, rooted tree representing the points of interrogation.

Next \ (n-1 \) rows, each row describes a tree edge. Each row contains two integers \ (U \) and \ (V \) , the node represents \ (U \) and \ (V \) between there is an edge.

Next \ (Q \) rows, each row describes an operation. The first \ (I \) line contains two integers, represent the first \ (I \) th query \ (P \) and \ (K \) .

\ (1 \ P \ N \)

\ (1 \ K \ N \)

\ (N \ the 300000 \)

\ (Q \ the 300000 \)

Output

Output \ (Q \) rows, each row corresponds to a query, the answer to the inquiry on behalf of.

Sample Input

5 3
1 2
1 3
2 4
4 5
2 2
4 1
2 3

Sample Output

3
1
3

\ (dfs \) make poor use of Fenwick tree maintenance.

Let's consider the practice of violence, we only find all distances \ (p \) or less \ (k \) of all the nodes, the answer plus node \ (size-1 \) .

Time complexity \ (O (^ n-2) \) .

Let's consider optimization.

In fact, we obtained only from a point less \ (K \) a \ (\ size SUM [I] -1 \) , the upper node can be calculated directly, we only use it to obtain all sub within the tree points to meet the conditions.

How do we find these quick point?

We found that only offline \ (dfs \) do poor maintenance of depth and can be.

code show as below

#include <cstdio>
#include <cstring>
#include <map>
#include <queue>
#include <iostream>
#include <algorithm>
 
using namespace std;
 
#define LL long long
#define int long long
#define u64 unsigned long long
#define Raed Read
#define reg register
#define debug(x) cerr<<#x<<" = "<<x<<endl;
#define rep(a,b,c) for(reg int a=(b),a##_end_=(c); a<=a##_end_; ++a)
#define ret(a,b,c) for(reg int a=(b),a##_end_=(c); a<a##_end_; ++a)
#define drep(a,b,c) for(reg int a=(b),a##_end_=(c); a>=a##_end_; --a)
#define erep(i,G,x) for(reg int i=(G).Head[x]; i; i=(G).Nxt[i])
 
inline int Read() {
    int res = 0, f = 1;
    char c;
    while (c = getchar(), c < 48 || c > 57)if (c == '-')f = 0;
    do res = (res << 3) + (res << 1) + (c ^ 48);
    while (c = getchar(), c >= 48 && c <= 57);
    return f ? res : -res;
}
 
template<class T>inline bool Min(T &a, T const&b) {
    return a > b ? a = b, 1 : 0;
}
template<class T>inline bool Max(T &a, T const&b) {
    return a < b ? a = b, 1 : 0;
}
 
const int N = 3e5 + 5, M = 3e5 + 5;
const LL mod = 998244353;
const int dx[5] = {1, -1, 0, 0, 0}, dy[5] = {0, 0, 0, 1, -1};
const  double eps = 1e-6;
 
bool MOP1;
 
int Ans[N], dep[N], Sz[N], Fa[N];
 
struct Link_list {
    int Head[N], Tot, Nxt[M << 1], to[M << 1];
    inline void AddEdgepair(int a, int b) {
        to[++Tot] = b, Nxt[Tot] = Head[a], Head[a] = Tot;
        to[++Tot] = a, Nxt[Tot] = Head[b], Head[b] = Tot;
    }
} G;
 
struct BIT {
    int C[N];
    inline void Add(int x, int y) {
        while (x < N)C[x] += y, x += x & -x;
    }
    inline int Sum(int x) {
        int res = 0;
        while (x)res += C[x], x -= x & -x;
        return res;
    }
} tr;
 
struct node {
    int b, id;
};
 
vector<node>Q[N];
 
void dfs(int x, int pre) {
    dep[x] = dep[pre] + 1, Sz[x] = 1, Fa[x] = pre;
    ret(i, 0, Q[x].size()) {
        int ID = Q[x][i].id, b = Q[x][i].b;
        Ans[ID] -= tr.Sum(dep[x] + b) - tr.Sum(dep[x]);
    }
    erep(i, G, x) {
        int y = G.to[i];
        if (y == pre)continue;
        dfs(y, x);
        Sz[x] += Sz[y];
    }
    ret(i, 0, Q[x].size()) {
        int ID = Q[x][i].id, b = Q[x][i].b;
        Ans[ID] += min(dep[x] - 1, b) * (Sz[x] - 1);
        Ans[ID] += tr.Sum(dep[x] + b) - tr.Sum(dep[x]);
    }
    tr.Add(dep[x], Sz[x] - 1);
}
 
bool MOP2;
 
inline void _main(void) {
    int n = Raed(), q = Read();
    ret(i, 1, n) {
        int a = Raed(), b = Raed();
        G.AddEdgepair(a, b);
    }
    rep(i, 1, q) {
        int a = Read(), b = Read();
        Q[a].push_back((node) {b, i});
    }
    dfs(1, 0);
    rep(i, 1, q)printf("%lld\n", Ans[i]);
}
 
signed main() {
#define offline1
#ifdef offline
    freopen("tree.in", "r", stdin);
    freopen("tree.out", "w", stdout);
    _main();
    fclose(stdin); fclose(stdout);
#else
    _main();
#endif
    return 0;
}

Guess you like

Origin www.cnblogs.com/dsjkafdsaf/p/11263272.html