QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#71425#5249. BanditsSorting#WA 2160ms117088kbC++6.0kb2023-01-10 00:27:202023-01-10 00:27:22

Judging History

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

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-01-10 00:27:22]
  • 评测
  • 测评结果:WA
  • 用时:2160ms
  • 内存:117088kb
  • [2023-01-10 00:27:20]
  • 提交

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 = 20 ;

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 , ll 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 , ll 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 , ll 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 ] ;
                ll 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 ) ;
                int wh = max ( ori[ x ][ op ] , ori[ y ][ op ] ) ;
                if ( treeid[ wh ][ op ] != 0 ) {
                    ans -= get_geq ( bad_roots[ treeid[ wh ][ op ] ] , lim ) ;
                }
                dummy = cen_prv[ dummy ] ;
            }
            cout << ans << "\n" ;
        }
    }
    return 0 ;
}



詳細信息

Test #1:

score: 100
Accepted
time: 2160ms
memory: 117088kb

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
5
2
2
3
4
4
7
8
9
11
10
14
12
12
10
11
10
10
9
10
11
11
9
15
11
14
13
14
16
11
17
15
13
15
14
14
20
15
20
22
22
20
17
23
23
24
29
24
26
30
31
36
28
37
39
35
34
45
39
46
45
43
46
42
49
44
50
43
47
52
50
49
57
51
56
61
58
68
66
69
69
61
63
67
63
72
74
78
72
73
78
77
73
85
76
86
82
85
76
82
8...

result:

ok 50000 lines

Test #2:

score: 0
Accepted
time: 999ms
memory: 87192kb

input:

100000
30038 18547 1594
65857 34063 4575
36600 72585 2328
99199 77595 1590
64257 48199 589
72301 40302 5083
69474 97536 606
60079 67381 9331
65982 39033 205
84122 65285 8508
18167 44905 3704
93490 94986 5941
27155 46374 6616
36232 62969 2212
79807 68652 7199
87352 59101 6880
94571 53224 3552
63610 8...

output:

0
1
3
3
3
3
4
6
10
10
12
14
14
16
18
19
19
19
19
22
22
23
23
23
23
24
25
26
26
26
26
26
26
28
31
31
31
31
31
34
34
36
40
41
41
42
42
42
42
42
44
44
44
47
48
48
48
48
48
48
48
48
48
49
50
50
53
54
54
55
55
56
56
56
56
56
59
62
62
62
62
62
62
62
62
62
62
63
65
67
69
69
69
73
73
73
74
76
76
76
76
76
79...

result:

ok 50000 lines

Test #3:

score: -100
Wrong Answer
time: 336ms
memory: 52184kb

input:

100000
61878 94907 27495452
40498 66053 163324081
9987 91760 269034612
88613 6169 634714395
87422 83687 263182872
22328 64374 595886322
57437 38976 201931120
75020 26926 516189886
88639 96262 269100132
88285 44915 173237252
88407 91931 174315082
12843 50312 641940581
13297 52746 120211351
89089 4638...

output:

0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
...

result:

wrong answer 853rd lines differ - expected: '0', found: '1'