萌新宝宝求助MLE
  • 板块P5114 八月脸
  • 楼主灵华
  • 当前回复0
  • 已保存回复0
  • 发布时间2023/2/14 16:27
  • 上次更新2023/10/24 00:49:05
查看原帖
萌新宝宝求助MLE
68882
灵华楼主2023/2/14 16:27

空间不知道哪里炸了啊/yun

#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
using namespace std ;

#define int long long
int read ( ) {
	char ch = getchar ( ) ;
	int x = 0 , f = 0 ;
	while ( ch < '0' || ch > '9' )
		f = ch == '-' , ch = getchar ( ) ;
	while ( ch >= '0' && ch <= '9' )
		x = x * 10 + ch - 48 , ch = getchar ( ) ;
	return x * ( f ? -1 : 1 ) ;
}

const int N = 100005 ;
int n , m , a[N] , b[N] , c[N] , ax , rt , siz[N] , tot ;
bool vis[N] ;
vector < int > ed[N] ;

void dfs0 ( int x , int la , int sz ) {
	siz [ x ] = 1 ;
	int axx = 0 ;
	for ( int y : ed [ x ] ) {
		if ( y == la || vis [ y ] ) continue ;
		dfs0 ( y , x , sz ) ;
		siz [ x ] += siz [ y ] ;
		axx = max ( axx , siz [ y ] ) ;
	}
	axx = max ( axx , sz - siz [ x ] ) ;
	if ( axx < ax ) ax = axx , rt = x ;
}

int sign ( int x ) { return x < 0 ? -1 : x > 0 ; }

struct Point {
	int x , y ;
	Point ( int _x = 0 , int _y = 0 ) :
		x ( _x ) , y ( _y ) { }
	Point operator + ( const Point u ) const { return { u .x + x , u .y + y } ; }
	Point operator - ( const Point u ) const { return { x - u .x , y - u .y } ; }
	bool operator < ( const Point u ) const { return x == u .x ? y < u .y : x < u .x ; }
	int det ( Point u ) { return x * u .y - y * u .x ; }
} ;

vector < Point > v0[N] , v1[N] , vc , ans , ret ;

int crossop ( Point q , Point p1 , Point p2 ) {
	return sign ( ( p1 - q ) .det ( p2 - q ) ) ;
}

int a0 , b0 , a1 , b1 ;
void dfs ( int x , int la ) {
	a0 += a [ x ] , b0 += b [ x ] ;
	a1 += a [ x ] , b1 += b [ x ] ;
	if ( c [ x ] )
		v1 [ tot ] .push_back ( Point ( a1 , b1 ) ) ;
	else
		v0 [ tot ] .push_back ( Point ( a0 , b0 ) ) ;
	siz [ x ] = 1 ;
	for ( int y : ed [ x ] ) {
		if ( y == la || vis [ y ] ) continue ;
		dfs ( y , x ) ;
		siz [ x ] += siz [ y ] ;
	}
	a0 -= a [ x ] , b0 -= b [ x ] ;
	a1 -= a [ x ] , b1 -= b [ x ] ;
}

vector < Point > convex ( vector < Point > ps ) {
	int n = ps .size ( ) , k = 0 ;
	if ( n <= 1 ) return ps ;
	sort ( ps .begin ( ) , ps .end ( ) ) ;
	vector < Point > qs ( n ) ;
	for ( int i = 0 ; i < n ; qs [ k ++ ] = ps [ i ++ ] )
		while ( k > 1 && crossop ( qs [ k - 2 ] , qs [ k - 1 ] , ps [ i ] ) >= 0 ) -- k ;
	qs .resize ( k ) ;
	return qs ;
}

vector < Point > conmerge ( vector < Point > ps , vector < Point > qs ) {
	int cnt = 0 , sp = ps .size ( ) , sq = qs .size ( ) ;
	if ( ! sp || ! sq ) return { } ;
	vector < Point > res ( sp + sq + 1 ) ;
	res [ 0 ] = ps [ 0 ] + qs [ 0 ] ;
	int i = 0 , j = 0 ;
	Point cp , cq ;
	while ( i < sp - 1 && j < sq - 1 ) {
		++ cnt ;
		cp = ps [ i + 1 ] - ps [ i ] ;
		cq = qs [ j + 1 ] - qs [ j ] ;
		if ( sign ( cp .det ( cq ) ) <= 0 )
			res [ cnt ] = res [ cnt - 1 ] + cp , ++ i ;
		else
			res [ cnt ] = res [ cnt - 1 ] + cq , ++ j ;
	}
	while ( i < sp - 1 ) ++ cnt , res [ cnt ] = res [ cnt - 1 ] + ps [ i + 1 ] - ps [ i ] , ++ i ;
	while ( j < sq - 1 ) ++ cnt , res [ cnt ] = res [ cnt - 1 ] + qs [ j + 1 ] - qs [ j ] , ++ j ;
	res .resize ( cnt + 1 ) ;
	return res ;
}

struct cmp {
	bool operator ( ) ( int x , int y ) {
		return v0 [ x ] .size ( ) + v1 [ x ] .size ( ) < v1 [ y ] .size ( ) + v0 [ y ] .size ( ) ;
	}
} ;
priority_queue < int , vector < int > , cmp > q ;

void solve ( int x ) {
	vis [ x ] = 1 ;
	tot = 1 ;
	v0 [ 1 ] .clear ( ) , v1 [ 1 ] .clear ( ) ;
	if ( c [ x ] )
		v1 [ 1 ] .push_back ( Point ( a [ x ] , b [ x ] ) ) ;
	else
		v0 [ 1 ] .push_back ( Point ( a [ x ] , b [ x ] ) ) ;
	q .push ( 1 ) ;
	for ( int y : ed [ x ] ) {
		if ( vis [ y ] ) continue ;
		++ tot ;
		v0 [ tot ] .clear ( ) , v1 [ tot ] .clear ( ) ;
		if ( c [ x ] )
			a0 = b0 = 0 , a1 = a [ x ] , b1 = b [ x ] ;
		else
			a0 = a [ x ] , b0 = b [ x ] , a1 = b1 = 0 ;
		dfs ( y , x ) ;
		v0 [ tot ] = convex ( v0 [ tot ] ) ;
		v1 [ tot ] = convex ( v1 [ tot ] ) ;
		q .push ( tot ) ;
	}
	ret .clear ( ) ;
	while ( tot > 1 ) {
		int x = q .top ( ) ; q .pop ( ) ;
		int y = q .top ( ) ; q .pop ( ) ;
		vc = conmerge ( v0 [ x ] , v1 [ y ] ) ;
		for ( auto u : vc ) ret .push_back ( u ) ;
		vc = conmerge ( v1 [ x ] , v0 [ y ] ) ;
		for ( auto u : vc ) ret .push_back ( u ) ;
		
		for ( auto u : v0 [ x ] ) v0 [ y ] .push_back ( u ) ;
		for ( auto u : v1 [ x ] ) v1 [ y ] .push_back ( u ) ;
		v0 [ y ] = convex ( v0 [ y ] ) ;
		v1 [ y ] = convex ( v1 [ y ] ) ;
		q .push ( y ) ; -- tot ;
	}
	while ( ! q .empty ( ) ) q .pop ( ) ;
	ret = convex ( ret ) ;
	for ( auto u : ret ) ans .push_back ( u ) ;
//	puts ( "\n" ) ;
	for ( int y : ed [ x ] ) {
		if ( vis [ y ] ) continue ;
		ax = n + 1 ;
		dfs0 ( y , x , siz [ y ] ) ;
		solve ( rt ) ;
	}
}

bool check ( Point u , int p ) {
	return u .y < p * u .x ;
}

int calc ( Point u , int x ) {
	return u .y - x * u .x ;
}

signed main ( ) {
// 	freopen ( "data.in" , "r" , stdin ) ;
	n = read ( ) , m = read ( ) ;
	for ( int i = 1 ; i <= n ; ++ i ) a [ i ] = read ( ) ;
	for ( int i = 1 ; i <= n ; ++ i ) b [ i ] = read ( ) ;
	for ( int i = 1 ; i <= n ; ++ i ) c [ i ] = read ( ) ;
	for ( int i = 1 ; i < n ; ++ i ) {
		int u = read ( ) , v = read ( ) ;
		ed [ u ] .push_back ( v ) ;
		ed [ v ] .push_back ( u ) ;
	}
	ax = n + 1 ;
	dfs0 ( 1 , 0 , n ) ;
	solve ( rt ) ;
	ans = convex ( ans ) ;
	int R = ans .size ( ) ;
	
	while ( m -- ) {
		int k = - read ( ) ;
		if ( R == 1 ) {
			cout << ans [ 0 ] .y - k * ans [ 0 ] .x << "\n" ;
			continue ;
		}
		int l = 0 , r = R - 2 , mid ;
//		int res = 0 ;
//		for ( int i = 0 ; i < R ; ++ i ) res = max ( res , calc ( ans [ i ] , k ) ) ;
		while ( l < r ) {
			mid = ( l + r ) >> 1 ;
			if ( check ( ans [ mid + 1 ] - ans [ mid ] , k ) )
				r = mid ;
			else l = mid + 1 ;
		}
		if ( r == R - 2 )
			cout << max ( calc ( ans [ r ] , k ) , calc ( ans [ r + 1 ] , k ) ) << "\n" ;
		else cout << calc ( ans [ r ] , k ) << "\n" ;
	}
	return 0 ;
}
2023/2/14 16:27
加载中...