QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#411052 | #7513. Palindromic Beads | Sorting | WA | 1ms | 5856kb | C++20 | 5.3kb | 2024-05-14 20:49:37 | 2024-05-14 20:49:38 |
Judging History
answer
#include<bits/stdc++.h>
using namespace std ;
typedef long long ll ;
typedef unsigned long long ull ;
typedef pair < int , int > pii ;
typedef vector < int > vi ;
#define fi first
#define se second
mt19937 rng(chrono::high_resolution_clock::now().time_since_epoch().count());
#define rep(i, a, b) for(int i = a; i < (b); ++i)
#define all(x) begin(x), end(x)
#define sz(x) (int)(x).size()
const int MAXN = 2e5 + 7 ;
const int LOG = 18 ;
const int MAXVAL = 3.5e7 ;
int n ;
vector < int > v[ MAXN ] ;
int lvl[ MAXN ] , LCA[ MAXN ][ LOG ] ;
vector < int > col[ MAXN ] ;
struct col_elem {
int x , y , dist , id ;
};
int tp ;
int st[ MAXN ] , en[ MAXN ] ;
void init ( int x , int prv ) {
st[ x ] = ++ tp ;
for ( int i = 1 ; i < LOG ; ++ i ) {
LCA[ x ][ i ] = LCA[ LCA[ x ][ i - 1 ] ][ i - 1 ] ;
}
for ( auto y : v[ x ] ) {
if ( y == prv ) { continue ; }
lvl[ y ] = lvl[ x ] + 1 ;
LCA[ y ][ 0 ] = x ;
init ( y , x ) ;
}
en[ x ] = tp ;
}
int get_lca ( int x , int y ) {
for ( int i = LOG - 1 ; i >= 0 ; -- i ) {
if ( lvl[ x ] - ( 1 << i ) >= lvl[ y ] ) {
x = LCA[ x ][ i ] ;
}
if ( lvl[ y ] - ( 1 << i ) >= lvl[ x ] ) {
y = LCA[ y ][ i ] ;
}
}
for ( int i = LOG - 1 ; i >= 0 ; -- i ) {
if ( LCA[ x ][ i ] != LCA[ y ][ i ] ) {
x = LCA[ x ][ i ] , y = LCA[ y ][ i ] ;
}
}
if ( x != y ) { x = LCA[ x ][ 0 ] ; }
return x ;
}
vector < col_elem > srt ;
int mx[ MAXVAL ] , pl[ MAXVAL ] , pr[ MAXVAL ] ;
int root[ 4 * MAXN ] ;
void tr_init ( int w , int l , int r ) {
root[ w ] = ++ tp ;
if ( l == r ) { return ; }
int mid = ( l + r ) / 2 ;
tr_init ( 2 * w , l , mid ) ;
tr_init ( 2 * w + 1 , mid + 1 , r ) ;
}
void update_inner ( int w , int l , int r , int wh , int val ) {
mx[ w ] = max ( mx[ w ] , val ) ;
if ( l == r ) { return ; }
int mid = ( l + r ) / 2 ;
if ( wh <= mid ) {
if ( pl[ w ] == 0 ) { pl[ w ] = ++ tp ; }
update_inner ( pl[ w ] , l , mid , wh , val ) ;
}
else {
if ( pr[ w ] == 0 ) { pr[ w ] = ++ tp ; }
update_inner ( pr[ w ] , mid + 1 , r , wh , val ) ;
}
}
void update_outer ( int w , int l , int r , int pos , int wh , int val ) {
update_inner( root[ w ] , 1 , n , wh , val ) ;
if ( l == r ) { return ; }
int mid = ( l + r ) / 2 ;
if ( pos <= mid ) { update_outer ( 2 * w , l , mid , pos , wh , val ) ; }
else { update_outer ( 2 * w + 1 , mid + 1 , r , pos , wh , val ) ; }
}
int qret ;
void query_inner ( int w , int l , int r , int st , int en ) {
if ( l > r || st > en ) { return ; }
if ( r < st || en < l ) { return ; }
if ( st <= l && r <= en ) {
qret = max ( qret , mx[ w ] ) ;
return ;
}
int mid = ( l + r ) / 2 ;
if ( pl[ w ] != 0 ) { query_inner ( pl[ w ] , l , mid , st , en ) ; }
if ( pr[ w ] != 0 ) { query_inner ( pr[ w ] , mid + 1 , r , st , en ) ; }
}
void query_outer ( int w , int l , int r , int st , int en , int aux_st , int aux_en ) {
if ( l > r || st > en ) { return ; }
if ( r < st || en < l ) { return ; }
if ( st <= l && r <= en ) {
query_inner ( root[ w ] , 1 , n , aux_st , aux_en ) ;
return ;
}
int mid = ( l + r ) / 2 ;
query_outer ( 2 * w , l , mid , st , en , aux_st , aux_en ) ;
query_outer ( 2 * w + 1 , mid + 1 , r , st , en , aux_st , aux_en ) ;
}
int dp[ MAXN ] ;
void solve ( ) {
cin >> n ;
for ( int i = 1 , x ; i <= n ; ++ i ) {
cin >> x ;
col[ x ].push_back ( i ) ;
}
for ( int i = 1 , x , y ; i < n ; ++ i ) {
cin >> x >> y ;
v[ x ].push_back ( y ) ;
v[ y ].push_back ( x ) ;
}
init ( 1 , -1 ) ;
for ( int i = 1 ; i <= n ; ++ i ) {
if ( col[ i ].size ( ) < 2 ) { continue ; }
int x = col[ i ][ 0 ] , y = col[ i ][ 1 ] ;
int dist = lvl[ x ] + lvl[ y ] - 2 * lvl[ get_lca ( x , y ) ] ;
srt.push_back ( { x , y , dist , i } ) ;
}
auto cmp = [ & ] ( col_elem p1 , col_elem p2 ) {
return ( p1.dist > p2.dist ) ;
};
sort ( srt.begin ( ) , srt.end ( ) , cmp ) ;
tp = 1 ;
tr_init ( 1 , 1 , n ) ;
int ans = 0 ;
for ( auto [ x , y , foo , id ] : srt ) {
qret = 0 ;
if ( lvl[ x ] > lvl[ y ] ) { swap ( x , y ) ; }
if ( st[ x ] <= st[ y ] && en[ y ] <= en[ x ] ) {
query_outer ( 1 , 1 , n , st[ y ] , en[ y ] , 1 , st[ x ] - 1 ) ;
query_outer ( 1 , 1 , n , st[ y ] , en[ y ] , en[ x ] + 1 , n ) ;
query_outer ( 1 , 1 , n , 1 , st[ x ] - 1 , st[ y ] , en[ y ] ) ;
query_outer ( 1 , 1 , n , en[ x ] + 1 , n , st[ y ] , en[ y ] ) ;
dp[ id ] = qret + 2 ;
if ( LCA[ y ][ 0 ] == x ) { ans = max ( ans , dp[ id ] ) ; }
else { ans = max ( ans , dp[ id ] + 1 ) ; }
}
else {
query_outer ( 1 , 1 , n , st[ x ] , en[ x ] , st[ y ] , en[ y ] ) ;
query_outer ( 1 , 1 , n , st[ y ] , en[ y ] , st[ x ] , en[ x ] ) ;
dp[ id ] = qret + 2 ;
ans = max ( ans , dp[ id ] + 1 ) ;
}
update_outer ( 1 , 1 , n , st[ x ] , st[ y ] , dp[ id ] ) ;
}
cout << ans << "\n" ;
}
int main ( ) {
ios_base :: sync_with_stdio ( false ) ;
cin.tie ( NULL ) ;
int t = 1 ; // cin >> t ;
while ( t -- ) { solve ( ) ; }
return 0 ;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 0ms
memory: 5776kb
input:
4 1 1 2 2 1 2 2 3 2 4
output:
3
result:
ok single line: '3'
Test #2:
score: 0
Accepted
time: 1ms
memory: 5648kb
input:
5 1 3 2 2 1 1 2 2 3 3 4 4 5
output:
4
result:
ok single line: '4'
Test #3:
score: 0
Accepted
time: 1ms
memory: 5776kb
input:
6 1 1 2 2 3 3 1 2 2 3 3 4 4 5 5 6
output:
2
result:
ok single line: '2'
Test #4:
score: -100
Wrong Answer
time: 1ms
memory: 5856kb
input:
6 1 2 3 4 5 6 1 2 2 3 3 4 4 5 5 6
output:
0
result:
wrong answer 1st lines differ - expected: '1', found: '0'