求调+求解

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

wind_rain @ 2024-10-13 17:32:42

代码如下,WA后四个点

#include<iostream>
#include<vector>
#include<math.h>
using namespace std;
const int MAX = 4e5 + 20;
const int LMAX = 30;
int n,m;
struct point {
    int fa = 0;
    int deep = 0;
    vector<int> son;
    vector<int> s,l,t;
}tree[MAX];
int appTime[MAX];

struct player {
    int from;
    int to;
}Run[MAX];

int faPoint;
int list[MAX] = {0};
int f[MAX][LMAX] = {0};
int lg[MAX] = {0};
bool flag = false;
void input () {
    cin >> n >> m;
    for (int i = 1; i < n; i++) {
        int u,v;
        cin >> u >> v;
        if (tree[u].fa != 0) swap(u,v);
        tree[u].fa = v;
        tree[v].son.push_back(u);
    }

    for (int i = 1; i <= n; i++) {
        if (tree[i].fa == 0) {
            faPoint = i;
        }

        cin >> appTime[i];
    }

    for (int i = 1; i <= m; i++) cin >> Run[i].from >> Run[i].to;

    lg[0] = -1;
    int d = 1;
    for (int i = 1; i <= MAX; i++) {
        lg[i] = lg[i - 1];
        if (d == i) {
            lg[i]++;
            d <<= 1;
        }
    }
}
void dfs (int x, int t) {
    tree[x].deep = t;
    for (int i = 0; i < tree[x].son.size(); i++) {
        dfs(tree[x].son[i], t + 1);
    }
}
void mark (int x) {
    int accu = 1;
    for (int k = 0; accu < tree[x].deep; k++) {
        if (k == 0) {
            f[x][k] = tree[x].fa;
        }
        else{
            f[x][k] = f[f[x][k - 1]][k - 1];
        }
        accu <<= 1;
    }
    for (int i = 0; i < tree[x].son.size(); i++) {
        mark(tree[x].son[i]);
    }
}
int LCA (int u, int v) {
    if (tree[u].deep < tree[v].deep) swap(u,v);
    while (tree[u].deep != tree[v].deep) u = f[u][lg[tree[u].deep - tree[v].deep]];

    if (u == v) return u;

    for (int k = lg[tree[u].deep - 1]; k >= 0; k--) {
        if (f[u][k] != f[v][k]) {
            u = f[u][k];
            v = f[v][k];
        }
    }

    return f[u][0];
}
void run () {
    // tree[0].deep = 1;
    dfs(faPoint, 1);
    mark(faPoint);
    for (int i = 1; i <= m; i++) {
        int lca = LCA(Run[i].from, Run[i].to);

        if (lca == 0) {
            flag = true;
            return;
        }

        list[i] = tree[Run[i].from].deep + tree[Run[i].to].deep - 2 * tree[lca].deep;

        tree[Run[i].from].s.push_back(i);
        tree[lca].l.push_back(i);
        tree[Run[i].to].t.push_back(i);
    }
}
int Depths[MAX] = {0}; // deep[s] = w[x] + deep[x]
int Deptht[MAX + MAX] = {0}; // list[t] - deep[i] = w[x] - deep[x]
int ans[MAX] = {0};
void dfs_ans (int x) {
    int curU = Depths[appTime[x] + tree[x].deep];
    int curV = Deptht[appTime[x] - tree[x].deep + MAX];
    for (int i = 0; i < tree[x].son.size(); i++) {
        dfs_ans(tree[x].son[i]);
    }

    Depths[tree[x].deep] += tree[x].s.size();
    for (int i = 0; i < tree[x].t.size(); i++) {
        Deptht[list[tree[x].t[i]] - tree[x].deep + MAX]++;
    }
    ans[x] += Depths[appTime[x] + tree[x].deep] + Deptht[appTime[x] - tree[x].deep + MAX] - curU - curV;
    for (int i = 0; i < tree[x].l.size(); i++) {
        if (tree[Run[tree[x].l[i]].from].deep == appTime[x] + tree[x].deep) ans[x]--;
        Depths[tree[Run[tree[x].l[i]].from].deep]--;
        Deptht[list[tree[x].l[i]] - tree[Run[tree[x].l[i]].to].deep + MAX]--;
    }
}
void output () {
    if (flag) return;
    dfs_ans(faPoint);

    for (int i = 1; i <= n; i++) {
        cout << ans[i] << " ";
    }
    cout << endl;
}

int main () {

    input();
    run();
    output();

    return 0;
}

很神奇的是,如果把96行的代码恢复,就会从WA变成TLE
求解qwq


by wind_rain @ 2024-10-14 20:49:38

@wind_rain 找到了,此帖结


|