/ SeriousOJ /

Record Detail

Accepted


  
# Status Time Cost Memory Cost
#1 Accepted 1ms 532.0 KiB
#2 Accepted 1ms 532.0 KiB
#3 Accepted 19ms 4.066 MiB
#4 Accepted 44ms 4.27 MiB
#5 Accepted 15ms 4.254 MiB
#6 Accepted 17ms 4.113 MiB
#7 Accepted 219ms 24.27 MiB
#8 Accepted 195ms 24.27 MiB
#9 Accepted 199ms 24.316 MiB
#10 Accepted 217ms 24.312 MiB
#11 Accepted 197ms 24.312 MiB
#12 Accepted 202ms 24.316 MiB
#13 Accepted 197ms 24.27 MiB
#14 Accepted 147ms 29.77 MiB
#15 Accepted 141ms 29.816 MiB
#16 Accepted 138ms 29.77 MiB

Code

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

// Fast IO
struct FastIO {
    FastIO() {
        ios::sync_with_stdio(false);
        cin.tie(NULL);
    }
};

// Segment Tree with Lazy Propagation
struct SegmentTree {
    int n;
    vector<long long> tree;
    vector<int> lazy;

    SegmentTree(int size) {
        n = size;
        tree.assign(4*n, 0);
        lazy.assign(4*n, 0);
    }

    // Build the segment tree
    void build(vector<int> &A, int idx, int l, int r) {
        if(l == r){
            tree[idx] = A[l];
            return;
        }
        int mid = (l + r) / 2;
        build(A, 2*idx, l, mid);
        build(A, 2*idx+1, mid+1, r);
        tree[idx] = tree[2*idx] + tree[2*idx+1];
    }

    // Push down the lazy updates
    void push(int idx, int l, int r){
        if(lazy[idx]){
            // Toggle operation: flip the bits in this segment
            tree[idx] = (r - l + 1) - tree[idx];
            if(l != r){
                lazy[2*idx] ^= 1;
                lazy[2*idx+1] ^= 1;
            }
            lazy[idx] = 0;
        }
    }

    // Update range [ql, qr]
    void update(int idx, int l, int r, int ql, int qr){
        push(idx, l, r);
        if(r < ql || l > qr) return;
        if(ql <= l && r <= qr){
            lazy[idx] ^= 1;
            push(idx, l, r);
            return;
        }
        int mid = (l + r) / 2;
        update(2*idx, l, mid, ql, qr);
        update(2*idx+1, mid+1, r, ql, qr);
        tree[idx] = tree[2*idx] + tree[2*idx+1];
    }

    // Query range [ql, qr]
    long long query(int idx, int l, int r, int ql, int qr){
        push(idx, l, r);
        if(r < ql || l > qr) return 0;
        if(ql <= l && r <= qr){
            return tree[idx];
        }
        int mid = (l + r) / 2;
        return query(2*idx, l, mid, ql, qr) + query(2*idx+1, mid+1, r, ql, qr);
    }
};

// Euler Tour to flatten the tree
struct EulerTour {
    int n;
    vector<vector<int>> adj;
    vector<int> in_time;
    vector<int> out_time;
    int timer;

    EulerTour(int size) {
        n = size;
        adj.assign(n+1, vector<int>());
        in_time.assign(n+1, 0);
        out_time.assign(n+1, 0);
        timer = 1;
    }

    void add_edge(int u, int v){
        adj[u].push_back(v);
        adj[v].push_back(u);
    }

    void dfs(int node, int parent){
        in_time[node] = timer;
        timer++;
        for(auto &child: adj[node]){
            if(child != parent){
                dfs(child, node);
            }
        }
        out_time[node] = timer -1;
    }
};

int main(){
    FastIO fio;

    int N;
    cin >> N;
    // 1-based indexing
    vector<int> A(N+1, 0);
    for(int i=1; i<=N; ++i){
        cin >> A[i];
    }

    EulerTour et(N);
    for(int i=0; i<N-1; ++i){
        int U, V;
        cin >> U >> V;
        et.add_edge(U, V);
    }

    // Perform Euler Tour
    et.dfs(1, -1);

    // Prepare array for segment tree based on Euler Tour
    // Map the original A to the Euler Tour order
    // We need to create an array where pos[in_time[node]] = A[node]
    vector<int> tour(N+1, 0); // 1-based
    for(int node=1; node<=N; ++node){
        tour[et.in_time[node]] = A[node];
    }

    // Initialize and build the segment tree
    SegmentTree st(N);
    st.build(tour, 1, 1, N);

    int Q;
    cin >> Q;
    while(Q--){
        int type, K;
        cin >> type >> K;
        if(type == 1){
            // Toggle operation
            st.update(1, 1, N, et.in_time[K], et.out_time[K]);
        }
        else if(type == 2){
            // Query operation
            long long res = st.query(1, 1, N, et.in_time[K], et.out_time[K]);
            cout << res << "\n";
        }
    }

    return 0;
}

Information

Submit By
Type
Submission
Problem
P1101 Mr. Heart and the Enchanted Lights
Contest
Brain Booster #6
Language
C++17 (G++ 13.2.0)
Submit At
2024-10-03 17:53:49
Judged At
2024-10-03 17:53:49
Judged By
Score
100
Total Time
219ms
Peak Memory
29.816 MiB