Submission #1369691

#TimeUsernameProblemLanguageResultExecution timeMemory
1369691vuvietTwo Currencies (JOI23_currencies)C++20
100 / 100
1361 ms32900 KiB
 /**
 *     Author:       trviet
 *     Studies at:   Le Hong Phong High School for the Gifted
**/

#include <bits/stdc++.h>

#define ____vuviet__ signed main
#define taskname "trvietbels"

using namespace std;

constexpr int maxn = 1e5 + 5, Log = 17;
int n, m, q, timer = 0, up[Log][maxn];
int h[maxn], st[maxn], en[maxn], lo[maxn], hi[maxn];

long long total_gold[maxn], res[maxn];
vector<int> tree[maxn];

struct metal
{
    long long gold, silver;
} bit[maxn];

struct Edge
{
    int u, v;
} e[maxn];

struct Checkpoints
{
    int p;
    long long c;
    bool operator < (Checkpoints o) const {
        return c < o.c;
    }
} pts[maxn];

struct Query
{
    int s, t;
    long long x, y;
} qr[maxn];

metal operator + (metal a, metal b)
{
    return {a.gold + b.gold, a.silver + b.silver};
}

metal operator - (metal a, metal b)
{
    return {a.gold - b.gold, a.silver - b.silver};
}

void update(int i, long long x, long long y)
{
    metal New = {x, y};
    for (; i <= n; i += i & -i)
        bit[i] = bit[i] + New;
}

metal get(int i)
{
    metal res = {0, 0};
    for (; i > 0; i -= i & -i)
        res = res + bit[i];
    return res;
}

metal cost(int l, int r)
{
    return get(r) - get(l - 1);
}

int GetBit(int x, int k)
{
    return (x >> k) & 1;
}

void DFSVisit(int u, int p)
{
    st[u] = ++timer, up[0][u] = p;
    for (int i = 1; i < Log; ++i)
        up[i][u] = up[i - 1][up[i - 1][u]];
    for (int v : tree[u])
        if (v != p)
            h[v] = h[u] + 1, DFSVisit(v, u);
    en[u] = timer;
}

int lca(int u, int v)
{
    if (h[u] < h[v]) swap(u, v);
    for (int i = Log - 1; i >= 0; --i)
        if (GetBit(h[u] - h[v], i))
            u = up[i][u];
    if (u == v) return u;
    for (int i = Log - 1; i >= 0; --i)
        if (up[i][u] != up[i][v])
            u = up[i][u], v = up[i][v];
    return up[0][u];
}

metal query(int u, int v)
{
    int k = lca(u, v);
    return get(st[u]) + get(st[v]) - (get(st[k]) + get(st[k]));
}

void UpdateEdge(int i, long long x, long long y)
{
    int u = e[i].u, v = e[i].v;
    if (h[u] < h[v]) swap(u, v);
    update(st[u], +x, +y), update(en[u] + 1, -x, -y);
}

void ReadData()
{
    cin >> n >> m >> q;
    for (int i = 1; i < n; ++i)
    {
        int u, v;
        cin >> u >> v;
        tree[u].push_back(v);
        tree[v].push_back(u);
        e[i] = {u, v};
    }
    DFSVisit(1, 0);
    for (int i = 1; i <= m; ++i)
    {
        cin >> pts[i].p >> pts[i].c;
        UpdateEdge(pts[i].p, 1, 0);
    }
    for (int i = 1; i <= q; ++i)
    {
        int s, t;
        long long x, y;
        cin >> s >> t >> x >> y;
        qr[i] = {s, t, x, y};
        total_gold[i] = query(s, t).gold;
        lo[i] = 1, hi[i] = m;
    }
}

void solvebytrvietbels()
{
    ReadData();
    sort(pts + 1, pts + 1 + m);
    vector<int> Q = {-1};
    while (!Q.empty())
    {
        Q.clear();
        for (int i = 1; i <= n; ++i)
            bit[i] = {0, 0};
        vector<vector<int>> queries(m + 5);
        for (int i = 1; i <= q; ++i)
            if (lo[i] <= hi[i])
            {
                queries[(lo[i] + hi[i]) / 2].push_back(i);
                Q.push_back(i);
            }
        for (int i = 1; i <= m; ++i)
        {
            UpdateEdge(pts[i].p, 1, pts[i].c);
            for (int id : queries[i])
            {
                metal cur = query(qr[id].s, qr[id].t);
                if (cur.silver <= qr[id].y) {
                    res[id] = cur.gold, lo[id] = i + 1;
                } else {
                    hi[id] = i - 1;
                }
            }
        }
    }
    for (int i = 1; i <= q; ++i)
    {
        long long need = total_gold[i] - res[i];
        cout << (need > qr[i].x ? -1 : qr[i].x - need) << "\n";
    }
}

void freopen_stdio(string speech)
{
    cin.tie(0)->sync_with_stdio(0);
    cerr << speech << "\n";
    if (fopen(taskname ".inp", "r"))
    {
        freopen(taskname ".inp", "r", stdin);
        freopen(taskname ".out", "w", stdout);
    }
}

____vuviet__()
{
    freopen_stdio("...miss you...");
    int t = 1;
    // cin >> t;
    while (t-- > 0)
        solvebytrvietbels();
    return 0;
}

Compilation message (stderr)

currencies.cpp: In function 'void freopen_stdio(std::string)':
currencies.cpp:189:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  189 |         freopen(taskname ".inp", "r", stdin);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
currencies.cpp:190:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  190 |         freopen(taskname ".out", "w", stdout);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...