답안 #837015

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
837015 2023-08-24T19:48:25 Z LucaIlie Two Currencies (JOI23_currencies) C++17
0 / 100
1 ms 2644 KB
#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() {
    ifstream cin( ".in" );
    ofstream cout( ".out" );
    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;
}

Compilation message

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() ) {
      |                 ~~^~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Incorrect 1 ms 2644 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 1 ms 2644 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 1 ms 2644 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 1 ms 2644 KB Output isn't correct
2 Halted 0 ms 0 KB -