关于点分治

P6626 [省选联考 2020 B 卷] 消息传递

Saka_Noa @ 2023-09-21 16:39:36

TLE 30 pts, 是我的常数太大了还是做法假了

#include<bits/stdc++.h>
using namespace std;
#define FR for(int i = head[u]; i ; i = e[i].next)
#define rp(i, a, b) for(int i = a;i <= b;i++)
const int N = 1e5 + 50;
struct edge { int next, to; } e[N << 1];
struct node { int id, k; }; 
int cnt, root, sum, t, n, m;
int head[N], dep[N], maxp[N], si[N], vis[N], dis[N], ans[N];
vector< node > Q[N];
void add(int f, int t) { e[++cnt] = edge{head[f], t}, head[f] = cnt; }
void clear() {
    memset(head, 0, sizeof head);
    cnt = 0;
    memset(vis, 0, sizeof vis);
    memset(ans, 0, sizeof ans);
    rp(i, 1, m) Q[i].clear();
}
void get_core(int u, int f) {
    si[u] = 1;
    maxp[u] = 0;
    FR {
        int v = e[i].to;
        if(v == f || vis[v]) continue;
        get_core(v, u);
        si[u] += si[v];
        maxp[u] = max(maxp[u], si[v]);
    }
    maxp[u] = max(maxp[u], sum - maxp[u]);
    if(!root || maxp[u] < maxp[root])
        root = u;
}
void get_dis(int u, int f, int opt) {
    dep[u] = dep[f] + 1;
    dis[dep[u]] += 1 * opt;
    FR {
        int v = e[i].to;
        if(vis[v] || v == f) continue;
        get_dis(v, u, opt);
    }
}
void dfs(int u, int f) {
    for(auto P : Q[u]) 
        if(P.k >= dep[u]) ans[P.id] += dis[P.k - dep[u]];  
    FR {
        int v = e[i].to;
        if(v == f || vis[v]) continue;
        dfs(v, u);
    }
}
void calc(int u) {
    memset(dis, 0, sizeof dis);
    dis[dep[u] = 0]++;
    FR {
        int v = e[i].to;
        if(vis[v]) continue;
        get_dis(v, u, 1);
    }
    FR {
        int v = e[i].to;
        if(vis[v]) continue;
        get_dis(v, u, -1);
        dfs(v, u);
        get_dis(v, u, 1);
    }
    for( auto P : Q[u]) 
        if(P.k >= dep[u]) ans[P.id] += dis[P.k];
}
void solve(int u) {
    calc(u);
    vis[u] = 1;
    for(int i = head[u]; i ; i = e[i].next) {
        int v = e[i].to;
        if(vis[v]) continue;
        get_core(v, u);
        sum = si[v];
        root = 0;
        get_core(v, u);
        solve(root);
    }
}
int main() {
    scanf("%d", &t);
    int u, v, x;
    while(t--) {
        scanf("%d %d", &n, &m);
        rp(i, 1, n - 1) {
            scanf("%d %d", &u, &v);
            add(u, v), add(v, u);
        } 
        rp(i, 1, m) {
            scanf("%d %d", &u, &x);
            Q[u].push_back( node {i, x} ); 
        }
        sum = n;
        get_core(1, 0);
        solve(root);
        rp(i, 1, m) printf("%d\n", ans[i]);
        clear();
    }

    return 0;
}

by 康立扬 @ 2023-10-03 20:14:08

Cu Ball


|