警示后人,树剖做法错误(大概)update
查看原帖
警示后人,树剖做法错误(大概)update
281668
FOX_konata楼主2022/8/7 10:44

如果把树剖的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之后
可能是第一篇题解和我用得是不同的方法?

2022/8/7 10:44
加载中...