QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#451461#8716. 树propane#RE 0ms3672kbC++208.5kb2024-06-23 13:51:322024-06-23 13:51:32

Judging History

你现在查看的是最新测评结果

  • [2024-06-23 13:51:32]
  • 评测
  • 测评结果:RE
  • 用时:0ms
  • 内存:3672kb
  • [2024-06-23 13:51:32]
  • 提交

answer

#include<iostream>
#include<cstring>
#include<vector>
#include<array>
#include<algorithm>
using namespace std;
using LL = long long;

// 1_based HLD
// struct Edge{
//     int to;
//     int w;
//     operator int() const { return to; }
// };

using Edge = int;
struct HLD{
    int n;
    vector<int> sz, top, dep, fa, in, out, seq;
    vector<vector<Edge> > g;
    int ts;

    HLD(const vector<vector<Edge> > &g, int root = 1) : n(int(g.size()) - 1), g(g)  {
        ts = 0;
        sz.resize(n + 1);
        top.resize(n + 1);
        dep.resize(n + 1);
        fa.resize(n + 1);
        in.resize(n + 1);
        out.resize(n + 1);
        seq.resize(n + 1);
        dep[root] = 1;
        top[root] = root;
        dfs_sz(root);
        dfs_hld(root);
    }

    void dfs_sz(int u){
        if (fa[u]){
            for(auto it = g[u].begin(); it != g[u].end(); it++){
                if (*it == fa[u]){
                    g[u].erase(it);
                    break;
                }
            }
        }
        sz[u] = 1;
        for(auto &j : g[u]){
            fa[j] = u;
            dep[j] = dep[u] + 1;
            dfs_sz(j);
            sz[u] += sz[j];
            if (sz[j] > sz[g[u][0]])
                swap(j, g[u][0]);
        }
    }

    void dfs_hld(int u){
        in[u] = ++ts;
        seq[in[u]] = u;
        for (auto j : g[u]){
            top[j] = (j == g[u][0] ? top[u] : j);
            dfs_hld(j);
        }
        out[u] = ts;
    }

    int lca(int u, int v){
        while (top[u] != top[v]){
            if (dep[top[u]] > dep[top[v]]){
                u = fa[top[u]];
            } 
            else{
                v = fa[top[v]];
            }
        }
        return dep[u] < dep[v] ? u : v;
    }

    int dist(int u, int v){
        return dep[u] + dep[v] - 2 * dep[lca(u, v)];
    }

    bool in_subtree(int u, int v){
        return in[v] <= in[u] && in[u] <= out[v];
    }
    
    int jump(int u, int k) {
        if (dep[u] < k){
            return -1;
        }
        int d = dep[u] - k;
        while (dep[top[u]] > d){
            u = fa[top[u]];
        }
        return seq[in[u] - dep[u] + d];
    }
    
    int rooted_lca(int a, int b, int c){
        return lca(a, b) ^ lca(b, c) ^ lca(c, a);
    }

    template<typename Q>
    void modify_path(int u, int v, const Q &q, bool edge = false){
        while(top[u] != top[v]){
            if (dep[top[u]] < dep[top[v]]) swap(u, v);
            q(in[top[u]], in[u]);
            u = fa[top[u]];        
        }
        if (dep[u] > dep[v]) swap(u, v);
        q(in[u] + edge, in[v]);
    }

    template<typename Q>
    void modify_subtree(int u, const Q &q){
        q(in[u], out[u]);
    }  

    template<typename T, typename Q>
    T query_path(int u, int v, const Q &q, bool edge = false){
        T ret = T();
        while(top[u] != top[v]){
            if (dep[top[u]] < dep[top[v]]) swap(u, v);
            ret = q(in[top[u]], in[u]) + ret;
            u = fa[top[u]];
        }
        if (dep[u] > dep[v]) swap(u, v);
        return q(in[u] + edge, in[v]) + ret;
    }

    template<typename T, typename Q>
    T query_subtree(int u, const Q &q){
        return q(in[u], out[u]);
    }

    template<typename T, typename Q, typename F>
    T query_path_noncommutative(int u, int v, const Q &q, const F &f, bool edge = false){
        T left = T(), right = T();
        while(top[u] != top[v]){
            if (dep[top[u]] < dep[top[v]]) swap(u, v), swap(left, right);
            left = q(in[top[u]], in[u]) + left;
            u = fa[top[u]];
        }
        if (dep[u] > dep[v]) swap(u, v), swap(left, right);
        return f(left, q(in[u] + edge, in[v]) + right);
    }
    
    pair<vector<int>, vector<pair<int, int> > > compress(vector<int> v){
        auto cmp = [&](int a, int b) { return in[a] < in[b]; };
        sort(v.begin(), v.end(), cmp);
        v.erase(unique(v.begin(), v.end()), v.end());
        const int k = (int)v.size();
        for(int i = 0; i + 1 < k; i++){
            v.push_back(lca(v[i], v[i + 1]));
        }
        sort(v.begin(), v.end(), cmp);
        v.erase(unique(v.begin(), v.end()), v.end());
        vector<pair<int, int> > edges;
        vector<int> stk;
        for(auto x : v){
            while(!stk.empty() && out[stk.back()] < in[x]){
                stk.pop_back();
            }
            if (!stk.empty()){
                edges.push_back({stk.back(), x});
            }
            stk.push_back(x);
        }
        return {v, edges};
    }

};

const int maxn = 2e5 + 5;
array<int, 2> dp[maxn][3];

int main(){

#ifdef LOCAL
    freopen("data.in", "r", stdin);
    freopen("data.out", "w", stdout);
#endif

    cin.tie(0);
    cout.tie(0);
    ios::sync_with_stdio(0);

    int n, m, q;
    cin >> n >> m >> q;
    vector<vector<int> > g(n + 1);
    for(int i = 0; i < n - 1; i++){
        int a, b;
        cin >> a >> b;
        g[a].push_back(b);
        g[b].push_back(a);
    }

    HLD hld(g);

    vector<int> b(m + 1);
    for(int i = 1; i <= m; i++) cin >> b[i];
    const int len = 450;

    vector<int> id(m + 1), L, R;
    const int INF = 1e9;
    vector<int> ok(n + 1);

    // 从x开始的三个是否可以
    auto check = [&](int i){
        int x = b[i], y = b[i + 1], z = b[i + 2];
        if (hld.in_subtree(x, y)){
            if (hld.in_subtree(y, z)) return true;
            int anc = hld.lca(x, z);
            return hld.dep[anc] <= hld.dep[y];
        }
        else if (hld.in_subtree(z, y)){
            if (hld.in_subtree(y, x)) return true;
            int anc = hld.lca(x, z);
            return hld.dep[anc] <= hld.dep[y];
        }
        return false;
    };

    auto build = [&](int id){
        int l = L[id], r = R[id];
        {
            int ans = 1, lastcnt = 1;
            for(int i = l + 1; i <= r; i++){
                if (lastcnt == 1){
                    lastcnt += 1;
                    ans += 1;
                }
                else{
                    if (ok[i - 2]){
                        lastcnt += 1;
                    }
                    else{
                        ans += 1;
                        lastcnt = 2;
                    }
                }
            }    
            dp[id][0] = {ans, lastcnt};
        }
        if (l - 1 >= 1){
            int ans = 0, lastcnt = 1;
            for(int i = l; i <= r; i++){
                if (lastcnt == 1){
                    lastcnt += 1;
                    ans += 1;
                }
                else{
                    if (ok[i - 2]){
                        lastcnt += 1;
                    }
                    else{
                        ans += 1;
                        lastcnt = 2;
                    }
                }
            }
            dp[id][1] = {ans, lastcnt};
        }
        else{
            dp[id][1] = {INF, INF};
        }
        if (l - 2 >= 1){
            int ans = 0, lastcnt = 2;
            for(int i = l; i <= r; i++){
                if (lastcnt == 1){
                    lastcnt += 1;
                    ans += 1;
                }
                else{
                    if (ok[i - 2]){
                        lastcnt += 1;
                    }
                    else{
                        ans += 1;
                        lastcnt = 2;
                    }
                }
            }
            dp[id][2] = {ans, lastcnt};
        }
        else{
            dp[id][2] = {INF, INF};
        }
    };

    for(int i = 1; i + 2 <= m; i++){
        ok[i] = check(i);
    }

    for(int i = 1, k = 0; i <= m; i += len, k += 1){
        int l = i, r = min(m, i + len - 1);
        for(int j = l; j <= r; j++){
            id[j] = k;
        }
        L.push_back(l);
        R.push_back(r);
        build(k);
    }

    auto get = [&](){
        auto [ans, lastcnt] = dp[0][0];
        for(int i = 1; i < L.size(); i++){
            ans += dp[i][lastcnt][0];
            lastcnt = dp[i][lastcnt][1];
        } 
        return ans;
    };

    for(int i = 0; i < q; i++){
        int x, y;
        cin >> x >> y;
        b[x] = y;
        for(int j = x - 2; j <= x; j++){
            if (j >= 1 and j + 2 <= n){
                ok[j] = check(j);
            }
        }
        build(id[x]);
        if (id[x] + 1 < L.size()) build(id[x] + 1);
        cout << get() << '\n';
    }

}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 0ms
memory: 3672kb

input:

5 5 3
2 1
3 2
1 4
5 1
1 5 4 2 3
1 3
5 3
3 3

output:

4
4
5

result:

ok 3 number(s): "4 4 5"

Test #2:

score: -100
Runtime Error

input:

30 200 200
10 24
10 13
10 26
13 29
27 26
17 24
27 21
17 15
13 5
13 30
27 3
18 21
9 21
2 24
10 4
11 5
2 8
10 23
1 18
21 25
4 20
12 23
22 27
28 27
18 7
13 6
14 30
10 19
16 21
14 29 25 30 1 17 22 21 11 19 21 30 13 1 22 10 14 7 29 7 15 21 25 29 25 7 29 7 1 23 3 17 2 7 4 27 18 26 3 6 5 3 16 26 20 19 16 2...

output:


result: