제출 #837020

#제출 시각아이디문제언어결과실행 시간메모리
837020LucaIlieTwo Currencies (JOI23_currencies)C++17
40 / 100
5020 ms55200 KiB
#include <bits/stdc++.h> #define int long long using namespace std; struct edge { int u, v; int other( int x ) { return u ^ v ^ x; } }; struct checkpoint { int e, c; }; struct query { int u, v, x, y; }; struct operation { char type; int val, u, v, q; }; struct answer { int sum, cnt; }; struct AIB { vector<int> aib; void init( int n ) { aib.resize( n + 1 ); for ( int i = 0; i < aib.size(); i++ ) aib[i] = 0; } void update( int i, int x ) { while ( i < aib.size() ) { aib[i] += x; i += (i & -i); } } int query( int i ) { int s = 0; while ( i > 0 ) { s += aib[i]; i -= (i & -i); } return s; } }; const int MAX_N = 2e5; const int MAX_M = 2e5; const int MAX_Q = 2e5; const int MAX_LOG_N = 17; int n, m; int leftBS[MAX_Q], rightBS[MAX_Q], ans[MAX_Q]; int depth[MAX_N + 1], leftPos[MAX_N + 1], rightPos[MAX_N + 1], parent[MAX_LOG_N + 1][MAX_N + 1]; edge edges[MAX_N]; checkpoint checkpoints[MAX_M + 1]; query queries[MAX_Q]; vector<operation> operations; vector<int> adj[MAX_N + 1]; AIB sum, cnt; int timee = 0; void dfs( int u, int p ) { parent[0][u] = p; depth[u] = depth[p] + 1; leftPos[u] = ++timee; for ( int e: adj[u] ) { int v = edges[e].other( u ); if ( v == p ) continue; dfs( v, u ); if ( u != edges[e].u ) swap( edges[e].u, edges[e].v ); } rightPos[u] = timee; } int lca( int u, int v ) { if ( depth[u] < depth[v] ) swap( u, v ); for ( int l = MAX_LOG_N; l >= 0; l-- ) { if ( depth[parent[l][u]] >= depth[v] ) u = parent[l][u]; } if ( u == v ) return u; for ( int l = MAX_LOG_N; l >= 0; l-- ) { if ( parent[l][u] != parent[l][v] ) { u = parent[l][u]; v = parent[l][v]; } } return parent[0][u]; } void initArb() { sum.init( n ); cnt.init( n ); for ( int i = 1; i <= m; i++ ) { int u = edges[checkpoints[i].e].v; cnt.update( leftPos[u], 1 ); cnt.update( rightPos[u] + 1, -1 ); } } void updateArb( int u, int val ) { sum.update( leftPos[u], val ); sum.update( rightPos[u] + 1, -val ); cnt.update( leftPos[u], -1 ); cnt.update( rightPos[u] + 1, 1 ); } answer queryArb( int u, int v ) { int l = lca( u, v ); return { sum.query( leftPos[u] ) + sum.query( leftPos[v] ) - 2 * sum.query( leftPos[l] ), cnt.query( leftPos[u] ) + cnt.query( leftPos[v] ) - 2 * cnt.query( leftPos[l] ) }; } signed main() { int q; cin >> n >> m >> q; for ( int i = 1; i < n; i++ ) cin >> edges[i].u >> edges[i].v; for ( int i = 1; i <= m; i++ ) cin >> checkpoints[i].e >> checkpoints[i].c; sort( checkpoints + 1, checkpoints + 1 + m, []( checkpoint a, checkpoint b ) { return a.c < b.c; } ); for ( int i = 0; i < q; i++ ) { cin >> queries[i].u >> queries[i].v >> queries[i].x >> queries[i].y; leftBS[i] = 0; rightBS[i] = m + 2; } for ( int i = 1; i < n; i++ ) { adj[edges[i].u].push_back( i ); adj[edges[i].v].push_back( i ); } dfs( 1, 0 ); for ( int l = 1; l <= MAX_LOG_N; l++ ) { for ( int u = 1; u <= n; u++ ) parent[l][u] = parent[l - 1][parent[l - 1][u]]; } for ( int pas = 0; pas < MAX_LOG_N + 1; pas++ ) { operations.clear(); for ( int i = 1; i <= m; i++ ) operations.push_back( { 'u', i, checkpoints[i].c, edges[checkpoints[i].e].v, 0 } ); for ( int i = 0; i < q; i++ ) operations.push_back( { 'q', (leftBS[i] + rightBS[i]) / 2, queries[i].u, queries[i].v, i } ); sort( operations.begin(), operations.end(), []( operation a, operation b ) { if ( a.val == b.val ) return (a.type == 'u'); return a.val < b.val; } ); initArb(); for ( operation o: operations ) { if ( o.type == 'u' ) updateArb( o.v, o.u ); else { auto x = queryArb( o.u, o.v ); if ( x.sum > queries[o.q].y ) rightBS[o.q] = o.val; else leftBS[o.q] = o.val; ans[o.q] = x.cnt; } } } for ( int i = 0; i < q; i++ ) cout << (ans[i] <= queries[i].x ? queries[i].x - ans[i] : -1) << "\n"; return 0; }

컴파일 시 표준 에러 (stderr) 메시지

currencies.cpp: In member function 'void AIB::init(long long int)':
currencies.cpp:37:28: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   37 |         for ( int i = 0; i < aib.size(); i++ )
      |                          ~~^~~~~~~~~~~~
currencies.cpp: In member function 'void AIB::update(long long int, long long int)':
currencies.cpp:42:19: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   42 |         while ( i < aib.size() ) {
      |                 ~~^~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...