結果

問題 No.2470 Gemini Tree(Ver.Jadeite)
ユーザー Yerin JungYerin Jung
提出日時 2023-09-23 23:54:07
言語 C++14
(gcc 12.3.0 + boost 1.83.0)
結果
AC  
実行時間 282 ms / 5,000 ms
コード長 5,025 bytes
コンパイル時間 1,803 ms
コンパイル使用メモリ 173,372 KB
実行使用メモリ 20,296 KB
最終ジャッジ日時 2023-09-23 23:54:21
合計ジャッジ時間 9,804 ms
ジャッジサーバーID
(参考情報)
judge15 / judge13
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 4 ms
13,624 KB
testcase_01 AC 4 ms
13,820 KB
testcase_02 AC 4 ms
13,628 KB
testcase_03 AC 4 ms
13,668 KB
testcase_04 AC 4 ms
13,692 KB
testcase_05 AC 4 ms
13,896 KB
testcase_06 AC 222 ms
17,352 KB
testcase_07 AC 222 ms
17,276 KB
testcase_08 AC 167 ms
17,160 KB
testcase_09 AC 178 ms
17,248 KB
testcase_10 AC 212 ms
17,280 KB
testcase_11 AC 160 ms
17,256 KB
testcase_12 AC 175 ms
17,272 KB
testcase_13 AC 204 ms
17,504 KB
testcase_14 AC 230 ms
17,516 KB
testcase_15 AC 197 ms
17,260 KB
testcase_16 AC 176 ms
17,260 KB
testcase_17 AC 207 ms
17,736 KB
testcase_18 AC 189 ms
17,192 KB
testcase_19 AC 188 ms
17,228 KB
testcase_20 AC 197 ms
17,400 KB
testcase_21 AC 282 ms
20,296 KB
testcase_22 AC 234 ms
17,280 KB
testcase_23 AC 187 ms
17,340 KB
testcase_24 AC 180 ms
17,252 KB
testcase_25 AC 200 ms
17,416 KB
testcase_26 AC 158 ms
17,164 KB
testcase_27 AC 168 ms
17,252 KB
testcase_28 AC 167 ms
17,108 KB
testcase_29 AC 189 ms
17,244 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#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 = 1e5 + 7 ;
const ll inf = 1e18 ;

int n , q ;
string s ;
int type[ MAXN ] ;
struct edge {
    int x , y , cost ;
};
edge a[ MAXN ] ;
vector < int > v[ MAXN ] ;
pii upd_list[ MAXN ] ;
ll ans[ MAXN ] ;

int lvl[ MAXN ] , subtree[ MAXN ] ;

void init ( int x , int prv ) {
    subtree[ x ] = 1 ;
    for ( auto y : v[ x ] ) {
        if ( y == prv ) { continue ; }
        lvl[ y ] = lvl[ x ] + 1 ;
        init ( y , x ) ;
        subtree[ x ] += subtree[ y ] ;
    }
}

int targ ;
int st[ MAXN ] , en[ MAXN ] ;
vector < int > ord ;

int spec_parent[ MAXN ] ;
int sub_sm[ MAXN ] ;
int rvpos[ MAXN ] ;

void setup ( int x , int prv , int hh ) {
    spec_parent[ x ] = hh ;
    if ( subtree[ x ] == targ ) {
        ord.push_back ( x ) ;
        st[ x ] = ord.size ( ) ;
        rvpos[ x ] = st[ x ] ;
        hh = x ;
    }
    else {
        st[ x ] = ord.size ( ) + 1 ;
    }
    sub_sm[ x ] = type[ x ] ;
    for ( auto y : v[ x ] ) {
        if ( y == prv ) { continue ; }
        setup ( y , x , hh ) ;
        sub_sm[ x ] += sub_sm[ y ] ;
    }
    en[ x ] = ord.size ( ) ;
}

class Tree {
public :
    ll tr[ 4 * MAXN ] , lazy[ 4 * MAXN ] ;
    void init ( int w , int l , int r ) {
        tr[ w ] = lazy[ w ] = 0 ;
        if ( l == r ) { return ; }
        int mid = ( l + r ) / 2 ;
        init ( 2 * w , l , mid ) ;
        init ( 2 * w + 1 , mid + 1 , r ) ;
    }
    void absorb ( int w , ll x ) {
        tr[ w ] += x ;
        lazy[ w ] += x ;
    }
    void push_lazy ( int w , int l , int r ) {
        if ( l != r ) { 
            absorb ( 2 * w , lazy[ w ] ) ;
            absorb ( 2 * w + 1 , lazy[ w ] ) ;
        }
        lazy[ w ] = 0 ;
    }
    void update ( int w , int l , int r , int st , int en , ll add ) {
        if ( l > r || st > en ) { return ; }
        if ( r < st || en < l ) { return ; }
        if ( st <= l && r <= en ) {
            absorb ( w , add ) ;
            return ;
        }
        push_lazy ( w , l , r ) ;
        int mid = ( l + r ) / 2 ;
        update ( 2 * w , l , mid , st , en , add ) ;
        update ( 2 * w + 1 , mid + 1 , r , st , en , add ) ;
        tr[ w ] = min ( tr[ 2 * w ] , tr[ 2 * w + 1 ] ) ;
    }
    ll query ( ) { return tr[ 1 ] ; }
};
Tree w ;

int spec_cnt ;

void add ( int id , ll val ) {
    int up = a[ id ].x , down = a[ id ].y ;
    if ( lvl[ up ] > lvl[ down ] ) { swap ( up , down ) ; }
    if ( spec_parent[ down ] != -1 ) {
        int wh = rvpos[ spec_parent[ down ] ] ;
        w.update ( 1 , 1 , spec_cnt , wh , wh , val * ( subtree[ down ] - sub_sm[ down ] ) ) ;
    }
    w.update ( 1 , 1 , spec_cnt , st[ down ] , en[ down ] , val * ( targ - sub_sm[ down ] ) ) ;

    if ( spec_parent[ down ] == -1 ) {
        w.update ( 1 , 1 , spec_cnt , 1 , st[ down ] - 1 , val * sub_sm[ down ] ) ;
        w.update ( 1 , 1 , spec_cnt , en[ down ] + 1 , spec_cnt , val * sub_sm[ down ] ) ;
    }
    else {
        int wh = rvpos[ spec_parent[ down ] ] ;        
        w.update ( 1 , 1 , spec_cnt , 1 , wh - 1 , val * sub_sm[ down ] ) ;
        w.update ( 1 , 1 , spec_cnt , wh + 1 , st[ down ] - 1 , val * sub_sm[ down ] ) ;
        w.update ( 1 , 1 , spec_cnt , en[ down ] + 1 , spec_cnt , val * sub_sm[ down ] ) ;
    }
}

void calc ( ) {
    ord.clear ( ) ;
    targ = 0 ;
    for ( int i = 1 ; i <= n ; ++ i ) {
        targ += type[ i ] ;
    }
    setup ( 1 , -1 , -1 ) ;
    spec_cnt = ord.size ( ) ;
    if ( spec_cnt == 0 ) { return ; }
    w.init ( 1 , 1 , spec_cnt ) ;
    for ( int i = 1 ; i < n ; ++ i ) {
        if ( a[ i ].cost > 0 ) {
            add ( i , a[ i ].cost ) ;
        }
    }
    for ( int i = 1 ; i <= q ; ++ i ) {
        add ( upd_list[ i ].fi , upd_list[ i ].se ) ;
        ans[ i ] = min ( ans[ i ] , w.query ( ) ) ;
    }
}

void solve ( ) {
    cin >> n ;
    cin >> s ;
    for ( int i = 1 ; i <= n ; ++ i ) {
        if ( s[ i - 1 ] == 'G' ) { type[ i ] = 1 ; }
        else { type[ i ] = 0 ; }
    }
    for ( int i = 1 ; i < n ; ++ i ) {
        cin >> a[ i ].x >> a[ i ].y >> a[ i ].cost ;
        v[ a[ i ].x ].push_back ( a[ i ].y ) ;
        v[ a[ i ].y ].push_back ( a[ i ].x ) ;
    }
    cin >> q ;
    for ( int i = 1 ; i <= q ; ++ i ) {
        cin >> upd_list[ i ].fi >> upd_list[ i ].se ;
        ans[ i ] = inf ;
    }
    init ( 1 , -1 ) ;

    calc ( ) ;
    for ( int i = 1 ; i <= n ; ++ i ) { type[ i ] ^= 1 ; }
    calc ( ) ;

    for ( int i = 1 ; i <= q ; ++ i ) {
        cout << ans[ i ] << "\n" ;
    }
}

int main ( ) {
    ios_base :: sync_with_stdio ( false ) ;
    cin.tie ( NULL ) ;
    int t = 1 ; // cin >> t ; 
    while ( t -- ) { solve ( ) ; }
    return 0 ;
}
0