• 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;
    }
    
  • 相关阅读:
    P3015 [USACO11FEB]最好的括号Best Parenthesis
    P1944 最长括号匹配_NOI导刊2009提高(1)
    P2328 [SCOI2005]超级格雷码
    P2308 添加括号
    P5657 格雷码【民间数据】
    P2196 挖地雷
    P5020 货币系统
    括号序列模型--序列dp--U86873 小Y的精灵国机房之旅
    P1033 自由落体
    P1017 进制转换
  • 原文地址:https://www.cnblogs.com/AWhiteWall/p/13046692.html
Copyright © 2020-2023  润新知