제출 #1296024

#제출 시각아이디문제언어결과실행 시간메모리
1296024fuyuTwo Currencies (JOI23_currencies)C++20
0 / 100
4 ms1796 KiB
#include <bits/stdc++.h>

using namespace std;

#define ll long long
#define pb push_back
#define ins insert
#define fi first
#define se second
#define ld long double
#define ALL(x) (x).begin(), (x).end()
#define MASK(x) (1ULL << (x))
#define BIT(x, k) ((x) >> (k) & 1)
#define TIME (1.0 * clock() / CLOCKS_PER_SEC)

template<typename T1, typename T2> bool maximize(T1 &x, const T2 &y){
    if (x < y){
        x = y;
        return 1;
    }
    return 0;
}

template<typename T1, typename T2> bool minimize(T1 &x, const T2 &y){
    if (x > y){
        x = y;
        return 1;
    }
    return 0;
}

bool ST_ALLOC;

#define file "CODE"

void fastio(){
    if (fopen(file".INP", "r")){
        freopen(file".INP", "r", stdin);
        freopen(file".OUT", "w", stdout);
    }
}

const int maxn = 1e5 + 9;

struct Station{
    int u, cost;

    friend istream &operator >> (istream &inp, Station &s){
        inp >> s.u >> s.cost;
        return inp;
    }
};

bool cmpStation(const Station &a, const Station &b){
    return a.cost < b.cost;
}

struct Query{
    int u, v, gc, sc;

    friend istream &operator >> (istream &inp, Query &q){
        inp >> q.u >> q.v >> q.gc >> q.sc;
        return inp;
    }
};

struct Node{
    int top, id;
};

int n, m, t, timer;
int sz[maxn];
int st[maxn];
int par[maxn];
int head[maxn];
int L[maxn];
int R[maxn];
int ans[maxn];
int belong[maxn];
ll gol[maxn];
ll sil[maxn];
Query q[maxn];
Station a[maxn];
vector<Node> adj[maxn];
vector<int> event[maxn];

void build(int u, int pre){
    sz[u] = 1;

    for(auto e : adj[u]){
        int v = e.top, id = e.id;

        if (v == pre)
            continue;

        belong[id] = v;

        build(v, u);

        sz[u] += sz[v];
    }
}

void hld(int u, int pre, int headNode){
    st[u] = ++timer;
    head[u] = headNode;

    int bigChild = -1;

    for(auto e : adj[u]){
        int v = e.top;

        if (v == pre)
            continue;

        par[v] = u;

        if (bigChild == -1)
            bigChild = v;

        if (sz[bigChild] < sz[v])
            bigChild = v;
    }

    if (bigChild != -1)
        hld(bigChild, u, headNode);

    for(auto e : adj[u]){
        int v = e.top;

        if (v == pre || v == bigChild)
            continue;

        hld(v, u, v);
    }
}

void upd(ll bit[], int pos, int val){
    if (pos <= 0)
        return;

    for(; pos <= n; pos += (pos & (-pos)))
        bit[pos] += val;
}

ll get(ll bit[], int pos){
    ll res = 0;

    for(; pos > 0; pos -= (pos & (-pos)))
        res += bit[pos];

    return res;
}

ll getRange(ll bit[], int l, int r){
    maximize(l, 1);

    if (l > r)
        return 0;

    return get(bit, r) - get(bit, l - 1);
}

void reset(){
    for(int i = 1; i <= n; ++i)
        gol[i] = sil[i] = 0;
}

int getGold(int u, int v){
    int res = 0;

    for(; head[u] != head[v]; u = par[head[u]]){
        if (st[u] < st[v])
            swap(u, v);

        res += getRange(gol, st[head[u]], st[u]);
    }

    if (u != v){
        if (st[u] > st[v])
            swap(u, v);

        res += getRange(gol, st[u] + 1, st[v]);
    }

    return res;
}

ll getSil(int u, int v){
    ll res = 0;

    for(; head[u] != head[v]; u = par[head[u]]){
        if (st[u] < st[v])
            swap(u, v);

        res += getRange(sil, st[head[u]], st[u]);
    }

    if (u != v){
        if (st[u] > st[v])
            swap(u, v);

        res += getRange(sil, st[u] + 1, st[v]);
    }

    return res;
}

bool EN_ALLOC;
signed main(){
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr); cout.tie(nullptr);

    fastio();

    cin >> n >> m >> t;

    for(int i = 1; i <= n - 1; ++i){
        int u, v; cin >> u >> v;

        adj[u].pb({v, i});
        adj[v].pb({u, i});
    }

    for(int i = 1; i <= m; ++i)
        cin >> a[i];

    for(int i = 1; i <= t; ++i)
        cin >> q[i];

    build(1, 1);

    for(int i = 1; i <= m; ++i)
        a[i].u = belong[a[i].u];

    sort(a + 1, a + m + 1, cmpStation);

    hld(1, 1, 1);

    memset(ans, -1, sizeof(ans));

    for(int i = 1; i <= t; ++i)
        L[i] = 0, R[i] = m;

    bool parallel = 1;

    while (parallel){
        parallel = 0;

        for(int i = 1; i <= t; ++i){
            if (L[i] > R[i])
                continue;

            int mid = L[i] + R[i] >> 1;

            event[mid].pb(i);
        
            parallel = 1;
        }

        if (!parallel)
            break;

        reset();

        for(int i = 1; i <= m; ++i){
            int u = a[i].u;

            upd(gol, st[u], 1);
        }

        for(int mid = 0; mid <= m; ++mid){
            if (mid){
                int node = a[mid].u, cost = a[mid].cost;

                upd(gol, st[node], -1);
                upd(sil, st[node], cost);
            }

            for(int idx : event[mid]){
                int u = q[idx].u, v = q[idx].v, gc = q[idx].gc, sc = q[idx].sc;

                int ng = getGold(u, v);
                ll ns = getSil(u, v);

                if (ng <= gc && ns <= sc)
                    maximize(ans[idx], gc - ng);

                if (ng <= gc && ns <= sc)
                    L[idx] = mid + 1;
                else if (ng <= gc && ns > sc)
                    R[idx] = mid - 1;
                else if (ng > gc && ns <= sc)
                    L[idx] = mid + 1;
                else
                    R[idx] = mid - 1;
            }

            if (event[mid].size())
                event[mid].clear();
        }
    }

    for(int i = 1; i <= t; ++i)
        cout << ans[i] << '\n';

    cerr << "Time ran : " << TIME << "s\n";
    cerr << "Static memory used : " << fixed << setprecision(2) << (((&EN_ALLOC) - (&ST_ALLOC)) / (1.0l * 1024 * 1024)) << "mb\n";
    return 0;
}

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

currencies.cpp: In function 'void fastio()':
currencies.cpp:38:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
   38 |         freopen(file".INP", "r", stdin);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
currencies.cpp:39:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
   39 |         freopen(file".OUT", "w", stdout);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...