1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
| #include "iostream" #include "algorithm" #include "cstring" #include "cstdio" using namespace std; #define MAXN 400006 #define max( a , b ) ( (a) > (b) ? (a) : (b) ) #define inf (1ll<<60) int n , m; int w[MAXN];
int head[MAXN] , to[MAXN << 1] , nex[MAXN << 1] , ecn; void ade( int u , int v ) { to[++ ecn] = v , nex[ecn] = head[u] , head[u] = ecn; }
struct mtrx { #define N 2 long long A[2][2]; inline void in( long long a , long long b ) { A[0][0] = A[0][1] = a , A[1][0] = b , A[1][1] = -inf; } inline long long re( ) { return max( A[0][0] , A[1][0] ); } inline mtrx operator * ( const mtrx& a ) const { mtrx ret; for( int i = 0 ; i < 2 ; ++ i ) for( int j = 0 ; j < 2 ; ++ j ) ret.A[i][j] = max( A[i][0] + a.A[0][j] , A[i][1] + a.A[1][j] ); return ret; } }; int ch[MAXN][2] , fa[MAXN]; long long dp[MAXN][2]; mtrx G[MAXN]; inline bool notroot( int u ) { return ch[fa[u]][0] == u || ch[fa[u]][1] == u; } inline void pu( int u ) { G[u].in( u[dp][0] , u[dp][1] ); if( ch[u][0] ) G[u] = G[ch[u][0]] * G[u]; if( ch[u][1] ) G[u] = G[u] * G[ch[u][1]]; } inline void rotate( int u ) { int f = fa[u] , g = fa[f] , w = ch[f][1]==u , k = ch[u][w^1]; if(notroot( f )) ch[g][ch[g][1]==f] = u;ch[f][w] = k , ch[u][w^1] = f; fa[f] = u , fa[k] = f , fa[u] = g; pu( f ) , pu( u ); } void splay( int x ) { int f , g; while( notroot( x ) ) { f = fa[x] , g = fa[f]; if( notroot( f ) ) rotate( (ch[f][0]==x)^(ch[g][0]==f) ? x : f ); rotate( x ); } } void access( int x ) { for( int p = 0 ; x ; ( p = x , x = fa[x] ) ) { splay(x); if( ch[x][1] ) x[dp][0] += G[ch[x][1]].re() , x[dp][1] += G[ch[x][1]].A[0][0]; if( p ) x[dp][0] -= G[p].re() , x[dp][1] -= G[p].A[0][0]; ch[x][1] = p; pu(x); } } void pre( int u , int f ) { dp[u][1] = w[u]; for( int i = head[u] ; i ; i = nex[i] ) { int v = to[i]; if( v == f ) continue; pre( v , u ); fa[v] = u; u[dp][0] += max( v[dp][0] , v[dp][1] ); u[dp][1] += v[dp][0]; } G[u].in( u[dp][0] , u[dp][1] ); } long long S; void mdfy( int u , long long x ) { access( u ) , splay( u ); dp[u][1] += x; pu( u ); } int main() { freopen("defense.in","r",stdin); freopen("defense.out","w",stdout); cin >> n >> m; scanf("%*s"); for( int i = 1 ; i <= n ; ++ i ) scanf("%d",&w[i]) , S += w[i]; for( int i = 1 , u , v ; i < n ; ++ i ) scanf("%d%d",&u,&v) , ade( u , v ) , ade( v , u ); pre( 1 , 1 );
int u , v , x1 , x2; while( m-- ) { scanf("%d%d%d%d",&u,&x1,&v,&x2); mdfy( u , x1 ? -inf : inf ) , mdfy( v , x2 ? -inf : inf ); S += ( ( x1 ^ 1 ) + ( x2 ^ 1 ) ) * inf; printf("%lld\n",S - G[v].re() > 1e10 ? -1 : S - G[v].re()); S -= ( ( x1 ^ 1 ) + ( x2 ^ 1 ) ) * inf; mdfy( u , x1 ? inf : -inf ) , mdfy( v , x2 ? inf : -inf ); } }
|