Submission #1353730

#TimeUsernameProblemLanguageResultExecution timeMemory
1353730Francisco_MartinTourists (EGOI22_tourists)C++20
100 / 100
779 ms62996 KiB
//EGOI 2022 Tourists
//https://qoj.ac/contest/2259/problem/5181

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vll = vector<ll>;
const ll MAXN = 2e5+5;

vll g[MAXN], h(MAXN,0); vector<vll> anc(18,vll(MAXN,0)); 
void dfs(ll v,ll p){
    anc[0][v]=p; h[v]=h[p]+1;
    for(auto u:g[v]) if(u!=p) dfs(u,v);
}
ll kanc(ll v,ll k){
    for(int i=0; i<18; i++) if((k>>i)&1) v=anc[i][v];
    return v;
}
ll lca(ll v,ll u){
    if(h[v]>h[u]) swap(v,u);
    u=kanc(u,h[u]-h[v]);
    if(v==u) return v;
    for(int i=17; i>=0; i--) if(anc[i][v]!=anc[i][u]){
        v=anc[i][v]; u=anc[i][u];
    }
    return anc[0][v];
}
ll dist(ll v,ll u){
    ll x=lca(v,u);
    return h[v]+h[u]-2*h[x];
}

struct node{ll city, lazy;};
vector<node> tree(4*MAXN); vll offset(MAXN,0);
void build(vll &A,ll x,ll lx,ll rx){
    if(rx-lx==1){tree[x]={((lx<(ll)A.size())?A[lx]:0),0}; return;}
    ll m=(lx+rx)/2; build(A,2*x+1,lx,m); build(A,2*x+2,m,rx);
    node a=tree[2*x+1], b=tree[2*x+2]; 
    tree[x]={((a.city==b.city)?a.city:0),0};
}
void push(ll x,ll lx,ll rx){
    if(rx-lx==1) return;
    node &a=tree[x], &b=tree[2*x+1], &c=tree[2*x+2];
    b.lazy+=a.lazy; c.lazy+=a.lazy; a.lazy=0;
    if(a.city!=0) b.city=c.city=a.city; 
}
void update(ll l,ll r,ll delta,ll x,ll lx,ll rx){
    if(r<=lx || rx<=l) return;
    if(l<=lx && rx<=r && tree[x].city!=0){
        if(tree[x].city!=delta){
            tree[x].lazy+=offset[tree[x].city]-dist(tree[x].city,delta)-offset[delta];
            tree[x].city=delta;
        }
        return;
    }
    push(x,lx,rx); ll m=(lx+rx)/2; 
    update(l,r,delta,2*x+1,lx,m); update(l,r,delta,2*x+2,m,rx);
    node a=tree[2*x+1], b=tree[2*x+2];
    tree[x].city=((a.city==b.city)?a.city:0);
}
pair<ll,ll> query(ll pos,ll x,ll lx,ll rx){
    if(rx-lx==1)return {tree[x].lazy,tree[x].city};
    push(x,lx,rx); ll m=(lx+rx)/2;
    if(pos<m) return query(pos,2*x+1,lx,m);
    return query(pos,2*x+2,m,rx);
}

int main(){
    ll n, m, q, sz=1, a, b, c; char op;
    cin >> n >> m >> q;
    vll A(m); while(sz<m) sz*=2;
    for(int i=0; i<m; i++) cin >> A[i];
    for(int i=0; i<n-1; i++){
        cin >> a >> b;
        g[a].push_back(b); g[b].push_back(a);
    }
    dfs(1,0); build(A,0,0,sz);
    for(int i=1; i<18; i++) for(int j=1; j<=n; j++) anc[i][j]=anc[i-1][anc[i-1][j]];
    for(int i=0; i<q; i++){
        cin >> op;
        if(op=='t') cin >> a >> b >> c, update(a-1,b,c,0,0,sz);
        if(op=='e') cin >> a >> b, offset[a]+=b;
        if(op=='q'){
            cin >> a; auto [x,y]=query(a-1,0,0,sz);
            cout << x+offset[y] << "\n";
        }
    }
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...