长链剖分求助

P3899 [湖南集训] 更为厉害

Custlo0793 @ 2021-10-10 13:00:38

样例没有过 ()

2天了 ()

#include <bits/stdc++.h>
#define rep(i,l,r) for (int i = l; i <= r; i ++)
#define per(i,r,l) for (int i = r; i >= l; i --)
using namespace std;
inline int read() {
    int x=0;char c = getchar();
    while(c > '9' || c < '0') c = getchar();
    while(c >= '0' && c <= '9') x = x * 10 + c - '0',c = getchar();
    return x;
}
const int M = 3e5 + 5;
int N,Q;
int Dep[M],Len[M],Son[M];
int top,tot,Fir[M],Nxt[M],ver[M],Size[M],NxtQ[M],FirQ[M],Qst[M],id[M],Ite[M],Node[M];
long long Result[M],Buc[M << 2],* cnt = Buc,* F[M],Tag[M];
inline void Link (int u,int v) {
    Nxt[++ top] = Fir[u],Fir[u] = top,ver[top] = v; return ; 
}
void Quest (int u,int Qt,int pos) {
    Ite[pos] = ++ tot,Node[tot] = u,NxtQ[tot] = FirQ[u],Qst[tot] = Qt,FirQ[u] = tot,id[tot] = pos; return ;
}
inline void Dfs1 (int u,int fa) {
    Dep[u] = Dep[fa] + 1,Size[u] = 1;
    for (int i = Fir[u]; i ; i = Nxt[i]) if (ver[i] != fa) {
        Dfs1 (ver[i],u),Size[u] += Size[ver[i]];
        if (Len[ver[i]] > Len[Son[u]]) Son[u] = ver[i];         
    }
    Len[u] = Len[Son[u]] + 1; return ;
}
inline void Dfs2 (int u,int fa) {
    if (Son[u]) {
        F[Son[u]] = F[u] + 1; Dfs2 (Son[u],u); 
        F[u][0] = 0; Tag[u] = Tag[Son[u]] + Size[Son[u]] - 1;
    }
    for (int i = Fir[u]; i ; i = Nxt[i]) if (ver[i] != Son[u] && ver[i] != fa) {
        F[ver[i]] = cnt,cnt += Len[ver[i]],Dfs2 (ver[i],u),Tag[u] += Tag[ver[i]] + Size[ver[i]] - 1;
        rep (j,1,Len[ver[i]]) F[u][j] += F[ver[i]][j - 1];
    } F[u][0] = - Tag[u];
    for (int i = FirQ[u]; i ; i = NxtQ[i]) 
        Result[id[i]] = F[u][min (Qst[i],Len[u] - 1)] + Tag[u];
    return ;
}
int main () {
    N = read (),Q = read ();
    rep (i,1,N - 1) {
        int u = read (),v = read ();
        Link (u,v),Link (v,u);
    }
    rep (i,1,Q) Quest (read (),read (),i); Dfs1 (1,0),F[1] = cnt,cnt += Len[1],Dfs2 (1,0);
    rep (i,1,Q) 
        printf("%lld\n", Result[i] + (long long) min (Dep[Node[Ite[i]]] - 1, Qst[Ite[i]]) * (Size[Node[Ite[i]]] - 1));
    return 0;
}

|