QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#71420#5249. BanditsSorting#WA 2046ms115544kbC++6.0kb2023-01-10 00:14:342023-01-10 00:14:34

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:14:34]
  • 评测
  • 测评结果:WA
  • 用时:2046ms
  • 内存:115544kb
  • [2023-01-10 00:14:34]
  • 提交

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'