Submission #1359062

#TimeUsernameProblemLanguageResultExecution timeMemory
1359062yogesh_saneTourists (EGOI22_tourists)C++20
0 / 100
0 ms344 KiB
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;

#define lc v<<1
#define rc (v<<1)+1

int timer, k;
vector<int> tin, tout, depth;
vector<vector<int>> ancestors, adj;

void dfs(int v, int p){
    tin[v] = ++timer;
    ancestors[v][0] = p;
    depth[v] = depth[p]+1;
    for(int i = 1; i <= k; i++)
        ancestors[v][i] = ancestors[ancestors[v][i-1]][i-1];
    for(auto u : adj[v])
        if(u != p)
            dfs(u,v);
    tout[v] = ++timer;
}
int is_ancestor(int u, int v){
    return tin[u] <= tin[v] && tout[u] >= tout[v];
}
int lca(int u, int v){
    if(is_ancestor(u,v))
        return u;
    if(is_ancestor(v,u))
        return v;
    for(int i = k; i >= 0; i--)
        if(!is_ancestor(ancestors[u][i],v))
            u = ancestors[u][i];
    return ancestors[u][0];
}
int distance(int u, int v){
    return depth[u] + depth[v] - 2*depth[lca(u,v)];
}
// leaf nodes store values for tourists
// higher level nodes store pending updates
// city value is set, opinion is added
// tree supports range updates and point queries

struct node {
    int city;
    long long opinion;
};
struct stree {
    vector<node>tree;
    stree(vector<int> &arr){
        tree.assign(4*(arr.size()-1),node());
        build(1,1,arr.size()-1,arr);
    }
    void build(int v, int tl, int tr, vector<int> &arr){
        if(tl == tr){
            tree[v].city = arr[tl];
        }else{
            int tm = (tl+tr)>>1;
            build(lc,tl,tm,arr);
            build(rc, tm+1,tr,arr);
            pushup(v);
        }
    }
    void pushup(int v){
        tree[v] = combine(tree[lc],tree[rc]);
    }
    node combine(node left, node right){
        node rtn;
        rtn.city = left.city == right.city ? left.city : 0;
        rtn.opinion = 0;
        return rtn;
    }
    void set_city(int v, int tl, int tr, int l, int r, int new_val){
        if(l > tr || r < tl)
            return;
        if(l <= tl && r >= tr){
            if(tree[v].city){
                tree[v].opinion -= distance(tree[v].city, new_val);
                tree[v].city = new_val;
                return;
            }
        }
        pushdown(v);
        int tm = (tl+tr)>>1;
        set_city(lc, tl, tm, l,r,new_val);
        set_city(rc, tm+1,tr,l,r,new_val);
        pushup(v);
    }
    void pushdown(int v){
        if(tree[v].city){
            tree[lc].city = tree[rc].city = tree[v].city;
            tree[v].city = 0;
        }
        if(tree[v].opinion){
            tree[lc].opinion += tree[v].opinion;
            tree[rc].opinion += tree[v].opinion;
            tree[v].opinion = 0;
        }
    }
    node get(int v, int tl, int tr, int pos){
        if(tl == tr){
            return tree[v];
        }else{
            pushdown(v);
            int tm = (tl+tr)>>1;
            if(pos <= tm)
                return get(lc,tl,tm,pos);
            else
                return get(rc,tm+1,tr,pos);
        }
    }
};
int main(){
    //freopen("in.txt","r", stdin);
    int n, m, q;
    cin >> n >> m >> q;
    vector<int> a(m+1);
    for(int i = 1; i <= m; i++)
        cin >> a[i];
    adj.assign(n+1,vector<int>());
    for(int i = 0; i < n-1; i++){
        int u, v;
        cin >> u >> v;
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    tin.assign(n+1,0);
    tout.assign(n+1,0);
    depth.assign(n+1,0);
    k = ceil(log2(n));
    ancestors.assign(n+1,vector<int>(k+1));
    dfs(1,1);    
    stree tourists(a);
    while(q--){
        char qtype;
        cin >> qtype;
        if(qtype == 't'){
            int f,g,c;
            cin >> f >> g >> c;
            tourists.set_city(1,1,m,f,g,c);
        }else if(qtype == 'e'){
            int c, d;
            cin >> c >> d;
            //not implemented
        }else if(qtype == 'q'){
            int v;
            cin >> v;
            cout << tourists.get(1,1,m,v).opinion << '\n';
        }
    }
    return 0;
}
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...