vijos1710 Mrw的工资计划

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#define ll long long
#define INF 2147483647
#define ll_INF 9223372036854775807
using namespace std;
inline int read(){
    int x = 0,tmp = 1;char ch = getchar();
    while( ch < '0' || ch > '9' ) {if ( ch == '-' ) tmp = -1; ch = getchar();}
    while( ch >= '0' && ch <= '9'){x = x * 10 + ch - '0'; ch = getchar(); }
    return x * tmp;
}
struct Point {
    int to, next;
} edge[21000];
int head[21000], idx = 0, w[21000], dep[21000], f[21000][16], sum[21000];
int maxdep, C[21000];
inline void ade( int u, int v ) {
    edge[++ idx].to = v;
    edge[idx].next = head[u];
    head[u] = idx;
}
void dfs( int x ) {
    for( int i = 1 ; i <= 15 ; ++ i ) {
        if( dep[x] < ( 1 << i ) ) break;
        f[x][i] = f[f[x][i - 1]][i - 1];
    }
    for( int i = head[x] ; i != -1 ; i = edge[i].next ) {
        int now = edge[i].to;
        dep[now] = dep[x] + 1;
        f[now][0] = x;
        if( dep[now] % 2 == 0 ) w[now] = -w[now];
        sum[now] = w[now] + sum[x];
        dfs( now );
    }
}
inline int lca( int u, int v ) {
    if( dep[u] > dep[v] ) swap( u, v );
    for( int i = 15 ; i >= 0 ; -- i ) if( dep[f[v][i]] >= dep[u] ) v = f[v][i];
    if( u == v ) return u;
    for( int i = 15 ; i >= 0 ; -- i ) if( f[v][i] != f[u][i] ) v = f[v][i], u = f[u][i];
    return f[u][0];
}
inline int query( int k ) {
    if( k < 1 ) return 0;
    int ret = 0;
    for( int i = k ; i ; i -= i&-i ) ret += C[i];
    return ret;
}
int main(){
    memset( dep, 0, sizeof( dep ) );
    memset( head, -1, sizeof( head ) );
    int N = read(), Q = read();
    for( int i = 1 ; i <= N ; ++ i ) w[i] = read();
    int boss;
    for( int i = 1 ; i <= N ; ++ i ) {
        int u = read();
        if( u == -1 ) {
            boss = i;
            continue;
        }
        ade( u, i );
    }
    dep[boss] = 1; sum[boss] = w[boss]; f[boss][0] = 0;
    dfs( boss );
    maxdep = 0;
    for( int i = 1 ; i <= N ; ++ i ) maxdep = max( maxdep, dep[i] );
    for( int i = 1 ; i <= Q ; ++ i ) {
        char ch = getchar();
        while( ch != 'M' && ch != 'A' ) ch = getchar();
        if( ch == 'M' ) {
            int lv = read(), t = read();
            if( lv % 2 == 0 ) t = -t;
            for( int i = lv ; i <= maxdep ; i += i&-i ) C[i] += t;
        } else {
            int x = read(), y = read();
            int k = lca( x, y );
            int ans = sum[x] + sum[y] + w[k] - 2 * sum[k] + query( dep[x] ) + query( dep[y] ) - query( dep[k] ) - query( dep[k] - 1 ); 
            printf( "%d\n", abs( ans ) );
        }
    }
 
    return 0;
}
 
/**************************************************************
    Problem: 1028
    User: ARZhu
    Language: C++
    Result: 正确
    Time:0 ms
    Memory:3428 kb
****************************************************************/
posted @ 2017-03-14 20:35  ARZhu  阅读(130)  评论(0)    收藏  举报