이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#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 = 1e5;
const int MAX_M = 1e5;
const int MAX_Q = 1e5;
const int MAX_LOG_N = 16;
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] = MAX_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 time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |