一个点WA就很气

P1600 [NOIP2016 提高组] 天天爱跑步

zzozz @ 2017-10-11 07:45:53

思路就是求lca搜索一个子树时在子树上相关的点打标记 计算桶的变化值,回溯是把以当前点为lca的相关点的桶值删掉,然后第13个点WA了

#include <vector>
#include <cstdio>
#include <cstring>
#include <iostream>
const int maxn = 300010;
const int maxm = 300010;
using namespace std;
vector <int> del[maxn];
bool vis[maxn];
int n, m, ecnt, qecnt;
int head[maxn], qhead[maxn], ans[maxn], cnt[maxn * 2], deep[maxn], fa[maxn], t[maxn];
struct Edge{
    int to, nex, fro, lca;
}es[maxn * 2], qes[maxm * 2];
int read(){
    int x = 0, f = 1;
    char ch;
    do {
        ch = getchar();
        if (ch == '-') f = -1;
    }while(ch < '0' || ch > '9');
    do {
        x = x * 10 + ch - 48;
        ch = getchar();
    }while(ch >= '0' && ch <= '9');
    return x * f;
}
void add(int u,int v){
    es[ecnt].to = v;
    es[ecnt].nex = head[u];
    head[u] = ecnt ++;
}
void qadd(int u,int v){
    qes[qecnt].to = v;
    qes[qecnt].fro = u;
    qes[qecnt].nex = qhead[u];
    qhead[u] = qecnt ++;
}
void Dfs(int u,int fa){
    for (int i = head[u];i != -1;i = es[i].nex){
        int v = es[i].to;
        if (v == fa) continue;
        deep[v] = deep[u] + 1;
        Dfs(v, u);
    }
}
int find(int x){return x == fa[x] ? x : fa[x] = find(fa[x]);}
void tarjan(int u){
    vis[u] = true;
    fa[u] = u;
    for (int i = head[u];i != -1;i = es[i].nex){
        int v = es[i].to;
        if (vis[v]) continue;
        tarjan(v);
        fa[v] = u;
    }
    for (int i = qhead[u];i != -1;i = qes[i].nex){
        int v = qes[i].to;
        if (vis[v]){
            qes[i].lca = find(v);
            qes[i ^ 1].lca = qes[i].lca;
        }
    }
}
void dfs(int u,int fa,int cnt1,int cnt2){
    for (int i = qhead[u];i != -1;i = qes[i].nex)
        if (i & 1){
            int v = qes[i].to;
            int lca = qes[i].lca;
            int dis = deep[v] + deep[u] - 2 * deep[lca];
            cnt[deep[u] - dis + maxn] ++;
        }
        else cnt[deep[u]] ++;
    for (int i = head[u];i != -1;i = es[i].nex){
        int v = es[i].to;
        if (v == fa) continue;
        dfs(v, u, cnt[deep[v] + t[v]], cnt[deep[v] - t[v] + maxn]);
    }
    ans[u] = cnt[deep[u] + t[u]] + cnt[deep[u] - t[u] + maxn] - cnt1 - cnt2;
    int len = del[u].size();
    for (int i = 0;i < len;i += 2){
        int st = del[u][i];
        int ed = del[u][i + 1];
        int dis = deep[st] + deep[ed] - 2 * deep[u];
        cnt[deep[st]] --;
        cnt[deep[ed] - dis + maxn] --;
        if (deep[u] - t[u] == deep[ed] - dis) ans[u] --;
    }
}
int main(){
    memset(head, -1, sizeof(head));
    memset(qhead, -1, sizeof(qhead));
    n = read(); m = read();
    for (int i = 1;i < n;i ++){
        int u, v;
        u = read();
        v = read();
        add(u, v);
        add(v, u);
    }
    for (int i = 1;i <= n;i ++) t[i] = read();
    for (int i = 1;i <= m;i ++){
         int u, v;
         u = read();
         v = read();
         qadd(u, v);
         qadd(v, u);
    }deep[1] = 1;
    Dfs(1, 1);
    tarjan(1);
    for (int i = 0;i < m;i ++){
         int lca = qes[i*2].lca;
         int u = qes[i*2].fro;
         int v = qes[i*2].to;
         del[lca].push_back(u);
         del[lca].push_back(v);
    }
    dfs(1, 1, 0, 0);
    for (int i = 1;i <= n;i ++) printf("%d ", ans[i]);
}

by zzozz @ 2017-10-11 15:20:22

没有灵性


by powerLEO101 @ 2017-10-12 06:36:05

dalao


by dengyixuan @ 2017-10-19 23:16:08

数组开大一倍,一开始我也是这样的


|