QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#71420 | #5249. Bandits | Sorting# | WA | 2046ms | 115544kb | C++ | 6.0kb | 2023-01-10 00:14:34 | 2023-01-10 00:14:34 |
Judging History
answer
#include<bits/stdc++.h>
using namespace std ;
typedef long long ll ;
typedef unsigned long long ull ;
typedef pair < ll , ll > pii ;
typedef vector<ll> vi;
#define fi first
#define se second
mt19937 rng(chrono::high_resolution_clock::now().time_since_epoch().count());
#define rep(i, a, b) for(ll i = a; i < (b); ++i)
#define all(x) begin(x), end(x)
#define sz(x) (ll)(x).size()
const int MAXN = 1e5 + 7 ;
const int LOG = 19 ;
struct node {
ll val ;
int cnt , prior ;
node *pl , *pr ;
node ( ) {
val = cnt = prior = 0 ;
pl = pr = nullptr ;
}
node ( ll x ) {
val = x ;
cnt = 1 ;
prior = rng ( ) ;
pl = pr = nullptr ;
}
};
int get_cnt ( node *w ) {
if ( w == nullptr ) { return 0 ; }
return w->cnt ;
}
void update ( node* w ) {
w->cnt = 1 + get_cnt ( w->pl ) + get_cnt ( w->pr ) ;
}
void split ( node* w , node* &l , node* &r , int sr ) {
if ( w == nullptr ) {
l = nullptr ; r = nullptr ;
return ;
}
if ( w->val <= sr ) {
split ( w->pr , w->pr , r , sr ) ;
l = w ;
update ( l ) ;
return ;
}
else {
split ( w->pl , l , w->pl , sr ) ;
r = w ;
update ( r ) ;
return ;
}
}
void merge ( node* &w , node* l , node *r ) {
if ( l == nullptr ) {
w = r ;
return ;
}
if ( r == nullptr ) {
w = l ;
return ;
}
if ( l->prior >= r->prior ) {
merge ( l->pr , l->pr , r ) ;
w = l ;
update ( w ) ;
}
else {
merge ( r->pl , l , r->pl ) ;
w = r ;
update ( w ) ;
}
}
void ins_num ( node* &w , int x ) {
node *foo1 , *foo2 ;
split ( w , foo1 , foo2 , x ) ;
node *nw = new node ( x ) ;
merge ( w , foo1 , nw ) ;
merge ( w , w , foo2 ) ;
}
int get_geq ( node *w , int sr ) {
if ( w == nullptr ) { return 0 ; }
if ( w->val < sr ) {
return get_geq ( w->pr , sr ) ;
}
return get_cnt ( w->pr ) + 1 + get_geq ( w->pl , sr ) ;
}
int n ;
struct edge {
int x , y , len ;
};
edge edgelist[ MAXN ] ;
vector < pii > v[ MAXN ] ;
int tot ;
bool used[ MAXN ] ;
int subtree[ MAXN ] ;
ll dist_to_cen[ MAXN ][ LOG ] ;
void init ( int x , int prv ) {
++ tot ;
subtree[ x ] = 1 ;
for ( auto [ y , len ] : v[ x ] ) {
if ( used[ y ] == true || y == prv ) { continue ; }
init ( y , x ) ;
subtree[ x ] += subtree[ y ] ;
}
}
int get_centroid ( int x , int prv ) {
for ( auto [ y , len ] : v[ x ] ) {
if ( used[ y ] == true || y == prv ) { continue ; }
if ( subtree[ y ] > ( tot / 2 ) ) {
return get_centroid ( y , x ) ;
}
}
return x ;
}
int ori[ MAXN ][ LOG ] ;
int treeid[ MAXN ][ LOG ] , tp ;
void set_up ( int x , int prv , int lvl ) {
for ( auto [ y , len ] : v[ x ] ) {
if ( used[ y ] == true || y == prv ) { continue ; }
dist_to_cen[ y ][ lvl ] = dist_to_cen[ x ][ lvl ] + len ;
if ( prv == -1 ) {
ori[ y ][ lvl ] = y ;
}
else {
ori[ y ][ lvl ] = ori[ x ][ lvl ] ;
}
set_up ( y , x , lvl ) ;
}
}
int cen_prv[ MAXN ] , cen_lvl[ MAXN ] ;
void decompose ( int x , int prv , int lvl ) {
tot = 0 ; init ( x , -1 ) ;
x = get_centroid ( x , -1 ) ;
tot = 0 ; init ( x , -1 ) ;
cen_lvl[ x ] = lvl ;
cen_prv[ x ] = prv ;
set_up ( x , -1 , lvl ) ;
used[ x ] = true ;
for ( auto [ y , foo ] : v[ x ] ) {
if ( used[ y ] == false ) {
treeid[ y ][ lvl ] = ++ tp ;
}
}
for ( auto [ y , foo ] : v[ x ] ) {
if ( used[ y ] == false ) {
decompose ( y , x , lvl + 1 ) ;
}
}
}
node* cen_root[ MAXN ] ;
vector < node* > bad_roots ;
int main ( ) {
ios::sync_with_stdio(false);
cin.tie(NULL);
cin >> n ;
for ( int i = 1 ; i < n ; ++ i ) {
cin >> edgelist[ i ].x >> edgelist[ i ].y >> edgelist[ i ].len ;
v[ edgelist[ i ].x ].push_back ( { edgelist[ i ].y , edgelist[ i ].len } ) ;
v[ edgelist[ i ].y ].push_back ( { edgelist[ i ].x , edgelist[ i ].len } ) ;
}
decompose ( 1 , -1 , 0 ) ;
for ( int i = 1 ; i <= n ; ++ i ) {
cen_root[ i ] = nullptr ;
}
bad_roots.resize ( tp + 1 ) ;
for ( int i = 0 ; i <= tp ; ++ i ) {
bad_roots[ i ] = nullptr ;
}
int q ; cin >> q ;
while ( q -- ) {
char type ;
cin >> type ;
if ( type == '+' ) {
int x , r ;
cin >> x >> r ;
int dummy = x ;
while ( dummy >= 0 ) {
int op = cen_lvl[ dummy ] ;
if ( dist_to_cen[ x ][ op ] <= r ) {
// printf ( "update %d %d %d %lld\n" , x , r , dummy , dist_to_cen[ x ][ op ] ) ;
// printf ( "adding %d to %d\n" , r - dist_to_cen[ x ][ op ] , dummy ) ;
ins_num ( cen_root[ dummy ] , r - dist_to_cen[ x ][ op ] ) ;
if ( treeid[ ori[ x ][ op ] ][ op ] != 0 ) {
ins_num ( bad_roots[ treeid[ ori[ x ][ op ] ][ op ] ] , r - dist_to_cen[ x ][ op ] ) ;
}
}
dummy = cen_prv[ dummy ] ;
}
}
else {
int id ; cin >> id ;
int x = edgelist[ id ].x , y = edgelist[ id ].y ;
if ( cen_lvl[ x ] < cen_lvl[ y ] ) { swap ( x , y ) ; }
int dummy = x ;
int ans = 0 ;
while ( dummy >= 0 ) {
int op = cen_lvl[ dummy ] ;
int lim = max ( dist_to_cen[ x ][ op ] , dist_to_cen[ y ][ op ] ) ;
ans += get_geq ( cen_root[ dummy ] , lim ) ;
// printf ( "asking %d for %d\n" , dummy , lim ) ;
if ( treeid[ ori[ x ][ op ] ][ op ] != 0 ) {
get_geq ( bad_roots[ treeid[ ori[ x ][ op ] ][ op ] ] , lim ) ;
}
dummy = cen_prv[ dummy ] ;
}
cout << ans << "\n" ;
}
}
return 0 ;
}
詳細信息
Test #1:
score: 0
Wrong Answer
time: 2046ms
memory: 115544kb
input:
100000 2670 75097 4080 87477 75802 1712 51835 36626 2883 19412 25923 5852 23976 19312 2520 82536 19514 2492 27160 66601 4483 99087 15088 3504 47050 58820 2964 37063 5696 9901 7717 1496 4891 79136 5448 4340 22575 81285 9289 96280 3803 9877 41980 32139 2855 44236 64938 3298 5983 99947 9666 95856 62545...
output:
0 0 0 2 2 14 2 2 6 10 7 12 19 18 19 19 31 26 27 19 20 20 21 20 19 19 19 28 30 21 24 24 24 33 24 37 32 22 36 30 31 47 30 36 44 45 38 32 41 49 43 55 50 49 56 58 67 75 70 75 73 82 92 83 94 89 76 92 89 90 92 102 91 98 106 89 86 122 110 114 112 122 139 124 140 141 131 137 134 129 131 138 147 144 156 161 ...
result:
wrong answer 6th lines differ - expected: '5', found: '14'