QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#577447#6885. Simple Tree ProblemJZYZ#AC ✓2634ms386088kbC++144.0kb2024-09-20 11:31:072024-09-20 11:31:07

Judging History

你现在查看的是最新测评结果

  • [2024-09-20 11:31:07]
  • 评测
  • 测评结果:AC
  • 用时:2634ms
  • 内存:386088kb
  • [2024-09-20 11:31:07]
  • 提交

answer

#include<bits/stdc++.h>
using namespace std ;

typedef long long LL ;
const int N = 1e6+5 ;

int n , a[N] , rk , cnt[N] ;
struct nn 
{
	int lst , to , val , id ;
}E[2*N] ;
int head[N] , tt0 ;
inline void add( int x , int y , int val , int id )
{
	E[++tt0] = (nn){head[x],y,val,id};
	head[x] = tt0 ;
}

struct Segment
{
	int l , r , Max ;
}tr[4*N] ;
void build1( int p , int l , int r )
{
	tr[p].l = l , tr[p].r = r , tr[p].Max = 0 ;
	if( l == r ) {
		tr[p].Max = cnt[l] ;
		return ;
	}
	int mid = (l+r)>>1 ;
	build1(p<<1,l,mid) ; build1(p<<1|1,mid+1,r) ;
	tr[p].Max = max( tr[p<<1].Max , tr[p<<1|1].Max ) ;
}
int query0( int p , int d )
{
	if( tr[p].Max < d ) return 0 ;
	if( tr[p].l == tr[p].r ) {
		return tr[p].l ;
	}
	if( tr[p<<1|1].Max >= d ) return query0( p<<1|1 , d ) ;
	return query0( p<<1 , d ) ;
}
struct Segtree
{
	int ls , rs , Max1 , Max2 ;
}t[24*N] ;
int tot , rt[N] ;
inline int build( int I ) 
{
	tot ++ ;
	t[tot].ls = t[tot].rs = 0 ;
	t[tot].Max1 = 0 ;
	t[tot].Max2 = tr[I].Max ;
	return tot ; 
}
int query1( int p , int l , int r , int d ) // Max1 >= d 的最大的 x 
{
	if( !p ) return 0 ;
	if( l == r ) {
		if( t[p].Max1 >= d ) return l ;
		return 0 ;
	}
	int mid = (l+r)>>1 ;
	if( t[t[p].rs].Max1 >= d ) return query1( t[p].rs , mid+1 , r , d ) ;
	return query1( t[p].ls , l , mid , d ) ;
}
int query2( int p , int I , int l , int r , int d ) // Max2 >= d 的最大的 x 
{
	if( t[p].Max2 < d ) return 0 ;
	if( l == r ) {
		if( t[p].Max2 >= d ) return l ;
		return 0 ;
	}
	int mid = (l+r)>>1 ;
	if( !t[p].rs && tr[I<<1|1].Max >= d ) {
		return query0( I<<1|1 , d ) ;
	}
	else if( t[p].rs && t[t[p].rs].Max2 >= d ) return query2( t[p].rs , I<<1|1 , mid+1 , r , d ) ;
	if( !t[p].ls ) {
		return query0( I<<1 , d ) ;
	}
	return query2( t[p].ls , I<<1 , l , mid , d ) ;
}
int Merge( int p , int q , int I , int l , int r )
{
	if( !p ) return q ;
	if( !q ) return p ;
	if( l == r ) {
		t[p].Max1 += t[q].Max1 ;
		t[p].Max2 -= cnt[l]-t[q].Max2 ;
		return p ;
	}
	int mid = (l+r)>>1 ;
	t[p].ls = Merge( t[p].ls , t[q].ls , I<<1 , l , mid ) ;
	t[p].rs = Merge( t[p].rs , t[q].rs , I<<1|1 , mid+1 , r ) ;
	t[p].Max1 = max( t[t[p].ls].Max1 , t[t[p].rs].Max1 ) ;
	t[p].Max2 = max( t[p].ls?t[t[p].ls].Max2:tr[I<<1].Max , t[p].rs?t[t[p].rs].Max2:tr[I<<1|1].Max ) ;
	return p ;
}
void modify( int p , int I , int l , int r , int x )
{
	if( l == r ) {
		t[p].Max1 ++ ;
		t[p].Max2 -- ;
		return ;
	}
	int mid = (l+r)>>1 ;
	if( x <= mid ) {
		if( !t[p].ls ) t[p].ls = build(I<<1) ;
		modify( t[p].ls , I<<1 , l , mid , x ) ;
	}
	else {
		if( !t[p].rs ) t[p].rs = build(I<<1|1) ;
		modify( t[p].rs , I<<1|1 , mid+1 , r , x ) ;
	}
	t[p].Max1 = max( t[t[p].ls].Max1 , t[t[p].rs].Max1 ) ;
	t[p].Max2 = max( t[p].ls?t[t[p].ls].Max2:tr[I<<1].Max , t[p].rs?t[t[p].rs].Max2:tr[I<<1|1].Max ) ;
}
int ans[N] ;
void dfs( int x , int fa )
{
	rt[x] = build(1) ;
	for(int i = head[x] ; i ; i = E[i].lst ) {
		int t = E[i].to ;
		if( t == fa ) continue ;
		dfs( t , x ) ;
		// 在 rt[t] 中求 E[i].id 的答案 
		ans[E[i].id] = max( query1( rt[t] , 1 , rk , E[i].val ) , query2( rt[t] , 1 , 1 , rk , E[i].val ) ) ;
		rt[x] = Merge( rt[x] , rt[t] , 1 , 1 , rk ) ;
	}
	modify( rt[x] , 1 , 1 , rk , a[x] ) ;
}
int b[N] ;
void solve()
{
	scanf("%d" , &n ) ;
	for(int i = 1 ; i <= n ; i ++ ) {
		scanf("%d" , &a[i] ) ;
		b[i] = a[i] ;
	}
	sort( b+1 , b+n+1 ) ;
	rk = unique( b+1 , b+n+1 ) - (b+1) ;
	for(int i = 1 ; i <= n ; i ++ ) {
		a[i] = lower_bound( b+1 , b+rk+1 , a[i] ) - b ;
		cnt[a[i]] ++ ;
	}
	build1( 1 , 1 , rk ) ;
	// [1,rk]
	int x , y , v ;
	for(int i = 1 ; i < n ; i ++ ) {
		scanf("%d%d%d" , &x , &y , &v ) ;
		add( x , y , v , i ) ;
		add( y , x , v , i ) ;
	}
	dfs( 1 , 0 ) ;
	for(int i = 1 ; i < n ; i ++ ) {
		printf("%d\n" , b[ans[i]] ) ;
	}
	tt0 = 0 ; tot = 0 ;
	for(int i = 1 ; i <= n ; i ++ ) {
		head[i] = 0 ;
		ans[i] = 0 ;
		cnt[i] = 0 ;
	}
}

int main()
{
	int t ;
	scanf("%d" , &t ) ;
	while( t -- ) solve() ;
	return 0 ;
}

详细

Test #1:

score: 100
Accepted
time: 2634ms
memory: 386088kb

input:

10000
96
378804736 378804736 101171470 683875564 378804736 997225055 448759149 683875564 683875564 997225055 152015654 83284224 229458933 101171470 229458933 448759149 448759149 152015654 101171470 600214219 378804736 997225055 448759149 152015654 229458933 229458933 83284224 997225055 229458933 600...

output:

997225055
997225055
0
997225055
997225055
997225055
997225055
997225055
997225055
997225055
997225055
997225055
997225055
997225055
997225055
997225055
997225055
997225055
997225055
997225055
997225055
997225055
997225055
997225055
997225055
997225055
997225055
997225055
997225055
997225055
99722505...

result:

ok 2494877 lines