/* Kasioopea 2014 * http://ksp.mff.cuni.cz/akce/kasiopea/ * * Autorské řešení úlohy 26-K-5: Mýtický strom * */ #include #include using namespace std; #define MaxN 200000 // Máme dva Fenwickovy stromy -- pro každou barvu jeden int fenwick[2][MaxN + 1]; void fenwick_pricti(int pozice, int x, int barva) { while (pozice <= MaxN) { fenwick[barva][pozice] += x; pozice += (pozice & -pozice); } } // Součet prvků na pozicích [0, ..., pozice] int fenwick_prefixovy_soucet(int pozice, int barva) { int soucet = 0; while (pozice != 0) { soucet += fenwick[barva][pozice]; pozice = pozice & (pozice - 1); } return soucet; } int N, M, T = 0; struct vrchol { int otec; int barva, pocatecni_hodnota; int hodnota; vector sousede; int L, R; } V[MaxN]; // Magická přičítací operace void pricti(int v, int x) { fenwick_pricti(V[v].L, x, V[v].barva); fenwick_pricti(V[v].R + 1, -x, V[v].barva); } // Vypisovací operace int urci_hodnotu(int v) { return V[v].pocatecni_hodnota + fenwick_prefixovy_soucet(V[v].L, V[v].barva) - fenwick_prefixovy_soucet(V[v].L, 1 - V[v].barva); } // Průchod do hloubky (DFS) každému vrcholu přiřadí barvu podle toho, zda leží // na liché či sudé hladině. Také vrcholy očísluje. Vrchol v má číslo V[v].L, všechny // vrcholy, které se nachází pod vrcholem v pak mají čísla V[v].L + 1 až V[v].R (včetně). void dfs(int v) { T++; V[v].L = T; for (int i = 0; i < V[v].sousede.size(); i++) { int w = V[v].sousede[i]; if (w != V[v].otec) { V[w].otec = v; V[w].barva = 1 - V[v].barva; dfs(w); } } V[v].R = T; } int main() { scanf("%d%d", &N, &M); for (int i = 0; i < N; i++) scanf("%d", &V[i].pocatecni_hodnota); int a, b; for (int i = 0; i < N - 1; i++) { scanf("%d%d", &a, &b); V[a].sousede.push_back(b); V[b].sousede.push_back(a); } V[0].otec = -1; dfs(0); for (int p = 0; p < M; p++) { char c; scanf(" %c", &c); if (c == 'P') { int v, x; scanf("%d%d", &v, &x); pricti(v, x); } else if (c == 'V') { int v; scanf("%d", &v); printf("%d\n", urci_hodnotu(v)); } } return 0; }