QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#111442 | #3232. Daylight | Sorting | 100 ✓ | 11681ms | 115824kb | C++20 | 6.5kb | 2023-06-07 06:52:29 | 2023-06-07 06:52:33 |
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 = 19 ;
int n , q ;
vector < int > v[ MAXN ] ;
vector < int > ord ;
int st[ MAXN ] , en[ MAXN ] , lvl[ MAXN ] ;
int rmq[ LOG ][ 2 * MAXN ] ;
int pwid[ 2 * MAXN ] ;
int anc[ MAXN ][ LOG ] ;
int small_n ;
void dfs ( int x , int prv ) {
ord.push_back ( x ) ;
st[ x ] = ord.size ( ) ;
for ( int i = 1 ; i < LOG ; ++ i ) {
anc[ x ][ i ] = anc[ anc[ x ][ i - 1 ] ][ i - 1 ] ;
}
for ( auto y : v[ x ] ) {
if ( y == prv ) { continue ; }
lvl[ y ] = lvl[ x ] + 1 ;
anc[ y ][ 0 ] = x ;
dfs ( y , x ) ;
ord.push_back ( x ) ;
}
en[ x ] = ord.size ( ) ;
}
int move_up ( int x , int cnt ) {
for ( int i = LOG - 1 ; i >= 0 ; -- i ) {
if ( cnt >= ( 1 << i ) ) {
cnt -= ( 1 << i ) ;
x = anc[ x ][ i ] ;
}
}
return x ;
}
int get_lca ( int x , int y ) {
int l = st[ x ] , r = st[ y ] ;
if ( l > r ) { swap ( l , r ) ; }
int len = r - l + 1 ;
int id = pwid[ len ] ;
int cand1 = rmq[ id ][ l ] , cand2 = rmq[ id ][ r - ( 1 << id ) + 1 ] ;
if ( lvl[ cand1 ] <= lvl[ cand2 ] ) { return cand1 ; }
return cand2 ;
}
int get_dist ( int x , int y ) {
int aux = get_lca ( x , y ) ;
return lvl[ x ] + lvl[ y ] - 2 * lvl[ aux ] ;
}
int used[ MAXN ] ;
int subtree[ MAXN ] , dep[ MAXN ] , mxdep[ MAXN ] ;
int cen_prv[ MAXN ] , cen_lvl[ MAXN ] ;
vector < int > sub_freq[ MAXN ] ;
vector < int > to_parent[ MAXN ] ;
int sub_freq_len[ MAXN ] ;
int vec_len[ MAXN ] ;
int tot_comp ;
void init ( int x , int prv ) {
++ tot_comp ;
subtree[ x ] = 1 ;
mxdep[ x ] = dep[ x ] ;
for ( auto y : v[ x ] ) {
if ( used[ y ] == 1 || y == prv ) { continue ; }
dep[ y ] = dep[ x ] + 1 ;
init ( y , x ) ;
subtree[ x ] += subtree[ y ] ;
mxdep[ x ] = max ( mxdep[ x ] , mxdep[ y ] ) ;
}
}
int get_centroid ( int x , int prv ) {
for ( auto y : v[ x ] ) {
if ( used[ y ] == 1 || y == prv ) { continue ; }
if ( 2 * subtree[ y ] > tot_comp ) {
return get_centroid ( y , x ) ;
}
}
return x ;
}
void add_up ( int x , int prv , int root , int type ) {
if ( x <= small_n ) {
if ( type == 0 ) {
++ sub_freq[ root ][ dep[ x ] ] ;
}
else {
++ to_parent[ root ][ dep[ x ] ] ;
}
}
for ( auto y : v[ x ] ) {
if ( used[ y ] == 1 || y == prv ) { continue ; }
add_up ( y , x , root , type ) ;
}
}
void decompose ( int x , int prv , int wh ) {
assert ( wh < LOG ) ;
dep[ x ] = tot_comp = 0 ; init ( x , -1 ) ;
x = get_centroid ( x , -1 ) ;
used[ x ] = 1 ; cen_prv[ x ] = prv ; cen_lvl[ x ] = wh ;
dep[ x ] = tot_comp = 0 ; init ( x , -1 ) ;
sub_freq[ x ].resize ( mxdep[ x ] + 1 , 0 ) ;
sub_freq_len[ x ] = mxdep[ x ] ;
add_up ( x , -1 , x , 0 ) ;
for ( int i = 1 ; i <= mxdep[ x ] ; ++ i ) {
sub_freq[ x ][ i ] += sub_freq[ x ][ i - 1 ] ;
}
for ( auto y : v[ x ] ) {
if ( used[ y ] == 1 ) { continue ; }
tot_comp = subtree[ y ] ;
int nxt_cen = get_centroid ( y , x ) ;
to_parent[ nxt_cen ].resize ( mxdep[ y ] + 1 , 0 ) ;
vec_len[ nxt_cen ] = mxdep[ y ] ;
add_up ( y , x , nxt_cen , 1 ) ;
for ( int i = 1 ; i <= mxdep[ y ] ; ++ i ) {
to_parent[ nxt_cen ][ i ] += to_parent[ nxt_cen ][ i - 1 ] ;
}
}
for ( auto y : v[ x ] ) {
if ( used[ y ] == 1 ) { continue ; }
decompose ( y , x , wh + 1 ) ;
}
}
int get_midway ( int x , int y ) {
int aux = get_lca ( x , y ) ;
int dist = get_dist ( x , y ) ;
if ( lvl[ x ] - lvl[ aux ] >= dist / 2 ) {
return move_up ( x , dist / 2 ) ;
}
else {
return move_up ( y , dist / 2 ) ;
}
}
int query ( int x , int mxdist ) {
int aux = x , wh = cen_lvl[ x ] ;
int ret = 0 , lst = 0 ;
while ( aux > 0 ) {
int hh = mxdist - get_dist ( x , aux ) ;
if ( hh >= 0 ) {
ret += sub_freq[ aux ][ min ( hh , sub_freq_len[ aux ] ) ] ;
if ( lst > 0 ) {
ret -= to_parent[ lst ][ min ( hh , vec_len[ lst ] ) ] ;
}
}
lst = aux ;
aux = cen_prv[ aux ] ;
-- wh ;
}
return ret ;
}
void solve ( ) {
cin >> n >> q ;
small_n = n ;
for ( int i = 1 ; i <= 2 * n ; ++ i ) {
v[ i ].clear ( ) ;
sub_freq[ i ].clear ( ) ;
to_parent[ i ].clear ( ) ;
sub_freq[ i ].shrink_to_fit ( ) ;
to_parent[ i ].shrink_to_fit ( ) ;
used[ i ] = 0 ;
}
for ( int i = 1 , x , y ; i < n ; ++ i ) {
cin >> x >> y ;
int aux = n + i ;
v[ x ].push_back ( aux ) ;
v[ aux ].push_back ( x ) ;
v[ aux ].push_back ( y ) ;
v[ y ].push_back ( aux ) ;
}
n = 2 * n - 1 ;
ord.clear ( ) ;
dfs ( 1 , -1 ) ;
for ( int i = 1 ; i <= 2 * n - 1 ; ++ i ) {
rmq[ 0 ][ i ] = ord[ i - 1 ] ;
}
for ( int k = 1 ; k < LOG ; ++ k ) {
for ( int i = 1 ; i + ( 1 << k ) - 1 <= 2 * n - 1 ; ++ i ) {
int cand1 = rmq[ k - 1 ][ i ] , cand2 = rmq[ k - 1 ][ i + ( 1 << ( k - 1 ) ) ] ;
if ( lvl[ cand1 ] <= lvl[ cand2 ] ) { rmq[ k ][ i ] = cand1 ; }
else { rmq[ k ][ i ] = cand2 ; }
}
}
decompose ( 1 , -1 , 0 ) ;
int lstans = 0 ;
while ( q -- ) {
int x , y , hh ;
cin >> x >> y >> hh ;
x = ( x + lstans ) % small_n + 1 , y = ( y + lstans ) % small_n + 1 , hh = ( hh + lstans ) % small_n ;
hh *= 2 ;
lstans = query ( x , hh ) + query ( y , hh ) ;
int sr = get_dist ( x , y ) ;
if ( sr <= 2 * hh ) {
int mid = get_midway ( x , y ) ;
// assert ( 1 <= mid && mid <= n ) ;
lstans -= query ( mid , ( 2 * hh - sr ) / 2 ) ;
}
cout << lstans << "\n" ;
}
}
int main ( ) {
ios_base :: sync_with_stdio ( false ) ;
cin.tie ( NULL ) ;
for ( int i = 1 ; i < 2 * MAXN ; ++ i ) {
pwid[ i ] = pwid[ i - 1 ] ;
while ( ( 1 << pwid[ i ] ) * 2 < i ) { ++ pwid[ i ] ; }
}
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: 11681ms
memory: 115824kb
input:
100 100000 100000 67672 73429 73429 62807 36128 73429 73429 97696 26524 73429 94290 73429 30735 73429 51707 73429 73429 52862 29620 73429 73429 951 31570 73429 73429 93564 13195 73429 37473 73429 38853 73429 73871 73429 31884 73429 61635 73429 73429 74144 74632 73429 73429 34214 63517 73429 11989 73...
output:
3 3 3 3 3 2 3 3 2 3 3 2 2 3 2 2 2 2 2 2 2 2 2 2 2 3 2 2 2 2 2 3 3 3 3 2 3 3 2 3 2 2 3 3 3 3 2 3 3 2 3 2 2 2 3 2 3 3 2 3 2 3 3 2 3 3 2 2 3 3 3 2 2 2 3 3 3 3 3 3 2 3 2 2 3 3 3 3 3 2 2 3 2 3 2 2 3 2 3 3 3 2 2 3 3 2 3 3 2 2 3 2 2 3 2 2 2 3 3 3 2 3 2 2 2 3 3 2 2 3 2 2 3 2 2 2 3 3 3 2 2 3 3 3 3 3 2 2 2 3 ...
result:
ok 1088007 lines