QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#451462#8716. 树propane#WA 2097ms5652kbC++208.5kb2024-06-23 13:52:192024-06-23 13:52:20

Judging History

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

  • [2024-06-23 13:52:20]
  • 评测
  • 测评结果:WA
  • 用时:2097ms
  • 内存:5652kb
  • [2024-06-23 13:52:19]
  • 提交

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(m + 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 <= m){
                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: 3780kb

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: 0
Accepted
time: 1ms
memory: 3804kb

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:

174
175
175
175
175
175
175
175
175
175
176
176
176
176
176
176
175
175
175
175
174
173
173
173
173
173
173
174
174
174
174
173
173
174
174
174
174
174
174
174
174
174
173
173
173
174
173
173
174
173
174
174
174
174
174
174
174
174
174
174
174
175
174
174
174
174
174
175
175
177
177
177
177
177
176
...

result:

ok 200 numbers

Test #3:

score: -100
Wrong Answer
time: 2097ms
memory: 5652kb

input:

1000 200000 200000
142 266
266 877
877 673
673 473
923 473
923 55
55 288
679 288
85 679
85 460
296 460
793 296
262 793
40 262
40 680
647 680
999 647
56 999
550 56
550 774
774 939
939 423
423 168
168 554
554 93
329 93
329 474
221 474
890 221
890 304
752 304
345 752
345 269
290 269
290 781
781 264
859...

output:

133561
133561
133561
133561
133561
133561
133561
133565
133565
133565
133565
133565
133565
133565
133565
133565
133565
133565
133565
133563
133563
133563
133563
133565
133565
133565
133565
133565
133565
133565
133565
133565
133565
133565
133565
133565
133565
133565
133563
133563
133563
133563
133563...

result:

wrong answer 1st numbers differ - expected: '133598', found: '133561'