CodeForces

Solution

(CF) 的数据是真的多而且慢

开个 (map) 记录就行了。这里在实现上有一个小坑:我注释里面是错误写法,因为第二个 (if) 可能会有 (2->1) 的情况。

Code

#include <map>
#include <cstdio>
#include <vector>
#include <iostream>
using namespace std;

const int N = 1e5 + 5;

int n, m, son[N], head[N], nxt[N << 1], to[N << 1], cnt, f[N][20], dep[N], siz[N], sum[N], len[N], be[N], maxx[N];
bool vis[N]; string s[N];
map <string, int> mp[N];
vector <int> q[N], ans[N];

int read() {
	int x = 0, f = 1; char s;
	while((s = getchar()) > '9' || s < '0') if(s == '-') f = -1;
	while(s <= '9' && s >= '0') x = (x << 1) + (x << 3) + (s ^ 48), s = getchar();
	return x * f;
}

void addEdge(const int u, const int v) {
	nxt[++ cnt] = head[u], to[cnt] = v, head[u] = cnt;
}

void dfs(const int u) {
    siz[u] = 1;
    for(int i = 1; i <= 18; ++ i) f[u][i] = f[f[u][i - 1]][i - 1];
    if(! head[u]) maxx[u] = dep[u];
    for(int i = head[u]; i; i = nxt[i]) {
        int v = to[i];
        dep[v] = dep[u] + 1;
        dfs(v);
        siz[u] += siz[v]; maxx[u] = max(maxx[v], maxx[u]);
        if(siz[son[u]] < siz[v]) son[u] = v;
    }
}

void cal(const int u, const int k) {
    /*mp[dep[u]][s[u]] += k;
    if(mp[dep[u]][s[u]] == 0) -- sum[dep[u]];
    if(mp[dep[u]][s[u]] == 1) ++ sum[dep[u]];*/
    if(! mp[dep[u]][s[u]]) ++ sum[dep[u]];
	mp[dep[u]][s[u]] += k;
	if(! mp[dep[u]][s[u]]) -- sum[dep[u]];
    for(int i = head[u]; i; i = nxt[i]) {
        int v = to[i];
        if(vis[v]) continue;
        cal(v, k);
    }
}

void solve(const int u, const int keep) {
    for(int i = head[u]; i; i = nxt[i]) {
        int v = to[i];
        if(v == son[u]) continue;
        solve(v, 0);
    }
    if(son[u]) solve(son[u], 1), vis[son[u]] = 1;
    cal(u, 1);
    if(son[u]) vis[son[u]] = 0;
    for(int i = 0, sz = q[u].size(); i < sz; ++ i) ans[u].push_back(sum[q[u][i]]);
    if(! keep) cal(u, -1);
}

int main() {
    int u, v;
    n = read();
    for(int i = 1; i <= n; ++ i) {
        cin >> s[i]; f[i][0] = read();
        addEdge(f[i][0], i);
    }
    dfs(0);
    m = read();
    for(int i = 1; i <= m; ++ i) {
        u = read(), v = read();
        if(dep[u] + v > maxx[u]) {be[i] = 0; continue;}
        q[u].push_back(dep[u] + v); be[i] = u;
    }
    solve(0, 1);
    for(int i = 1; i <= m; ++ i)
    	if(! be[i]) puts("0");
    	else printf("%d
", ans[be[i]][len[be[i]] ++]);
    return 0;
}
原文地址:https://www.cnblogs.com/AWhiteWall/p/13046692.html