如果把树剖的update写成这样第一篇题解里的这样
void update( int u , ll w ){
Matrix< 2 , 1 > New , Old;
M[ u ]( 1 , 0 ) += w - a[ u ] , a[ u ] = w;
while( u ){
Old = query( top[ u ] );
seg.update( 1 , n , dfn[ u ] , 1 );
New = query( top[ u ] );
u = fa[ top[ u ] ];
// M[ u ]( 0 , 0 ) = M[ u ]( 1 , 0 ) +=
// max( New( 0 , 0 ) , New( 0 , 1 ) ) - max( Old( 0 , 0 ) , Old( 0 , 1 ) );
// M[ u ]( 0 , 1 ) = New( 0 , 0 ) - Old( 0 , 0 );
M[ u ]( 0 , 0 ) = M[ u ]( 0 , 1 ) +=
max( New( 0 , 0 ) , New( 1 , 0 ) ) - max( Old( 0 , 0 ) , Old( 1 , 0 ) );
M[ u ]( 1 , 0 ) += New( 0 , 0 ) - Old( 0 , 0 );
}
}
你会发现你阳历都过不去
但是如果你写成这样
void update( int u , ll w ){
Matrix< 2 , 1 > New , Old;
M[ u ]( 1 , 0 ) += w - a[ u ];
Old = query( top[ u ] );
a[ u ] = w;
while( u ){
seg.update( 1 , n , dfn[ u ] , 1 );
New = query( top[ u ] );
u = fa[ top[ u ] ];
M[ u ]( 0 , 0 ) = M[ u ]( 0 , 1 ) +=
max( New( 0 , 0 ) , New( 1 , 0 ) ) - max( Old( 0 , 0 ) , Old( 1 , 0 ) );
M[ u ]( 1 , 0 ) += New( 0 , 0 ) - Old( 0 , 0 );
Old = query( top[ u ] );
}
}
就能AC
第二个写法的关键就是a[ u ]更新在计算old之后
可能是第一篇题解和我用得是不同的方法?