Submission #1361060

#TimeUsernameProblemLanguageResultExecution timeMemory
1361060iamhereforfunTwo Currencies (JOI23_currencies)C++20
0 / 100
968 ms49328 KiB
// Starcraft 2 enjoyer //

#include <bits/stdc++.h>

// #pragma GCC target("avx2")
// #pragma GCC optimize("O3")
// #pragma GCC optimize("unroll-loops")

using namespace std;

#define LSOne(X) ((X) & -(X))
#define int long long

const int N = 1e5 + 5;
const int M = 1 << 15;
const int B = 18;
const long long K = 2;
const int LG = 20;
const int INF = 2e9 + 5;
const int P = 31;
const int MOD = 1e9 + 7;
const int nx[] = {0, 1, 0, -1}, ny[] = {-1, 0, 1, 0};

struct Fenwick
{
    vector<int> ft;
    int n;
    Fenwick(int len)
    {
        n = len;
        ft.assign(n + 1, 0);
    }
    void update(int pos, int val)
    {
        while (pos <= n)
        {
            ft[pos] += val;
            pos += LSOne(pos);
        }
    }
    int get(int pos)
    {
        int sum = 0;
        while (pos > 0)
        {
            sum += ft[pos];
            pos -= LSOne(pos);
        }
        return sum;
    }
    int get(int l, int r)
    {
        return get(r) - get(l - 1);
    }
};

int n, m, q, top[N], par[N], in[N], cid, bigchild[N], val[N], l[N], r[N], ans[N], num[N];
vector<int> adj[N];
vector<pair<int, int>> edge;
vector<array<int, 3>> edges;
array<int, 4> query[N];
vector<int> update[N];

int dfs1(int c, int p)
{
    par[c] = p;
    int j = -1;
    int sz = 0;
    bigchild[c] = -1;
    for (int i : adj[c])
    {
        if (i == p)
            continue;
        int s = dfs1(i, c);
        if (s > j)
        {
            j = s;
            bigchild[c] = i;
        }
        sz += s;
    }
    sz++;
    return sz;
}

void dfs2(int c, int p)
{
    top[c] = p;
    in[c] = cid++;
    if (bigchild[c] == -1)
        return;
    dfs2(bigchild[c], p);
    for (int i : adj[c])
    {
        if (i == par[c] || i == bigchild[c])
            continue;
        dfs2(i, i);
    }
}

bool cmp(array<int, 3> &a, array<int, 3> &b)
{
    return a[2] < b[2];
}

inline void solve()
{
    cin >> n >> m >> q;
    edges.push_back({n, n, -INF});
    for (int x = 1; x <= n - 1; x++)
    {
        int a, b;
        cin >> a >> b;
        adj[a].push_back(b);
        adj[b].push_back(a);
        edge.push_back({a, b});
    }
    for (int x = 0; x < m; x++)
    {
        int i, w;
        cin >> i >> w;
        auto &[a, b] = edge[i - 1];
        edges.push_back({a, b, w});
        // cout << a << " " << b << " " << w << "\n";
    }
    cid = 1;
    dfs1(1, 0);
    dfs2(1, 1);
    sort(edges.begin(), edges.end(), cmp);
    for (int x = 0; x < q; x++)
    {
        int s, t, a, b;
        cin >> s >> t >> a >> b;
        query[x] = {s, t, a, b};
        l[x] = 0, r[x] = m, ans[x] = 0;
    }
    for (int x = 0; x < LG; x++)
    {
        Fenwick ft1(n + 1), ft2(n + 1);
        for (int y = 1; y <= m; y++)
        {
            update[y].clear();
            auto &[a, b, w] = edges[y];
            if (par[b] == a)
                swap(a, b);
            ft2.update(in[a], 1);
        }
        for (int y = 0; y < q; y++)
        {
            if (l[y] > r[y])
                continue;
            int m = (l[y] + r[y]) / 2;
            update[m].push_back(y);
        }
        for (int y = 0; y <= m; y++)
        {
            auto &[a, b, w] = edges[y];
            if (par[b] == a)
                swap(a, b);
            if (y > 0)
            {
                ft1.update(in[a], w);
                ft2.update(in[a], -1);
            }
            for (int i : update[y])
            {
                auto [a, b, g, s] = query[i];
                int sum = 0, cnt = 0;
                for (; top[a] != top[b]; a = par[top[a]])
                {
                    if (in[top[a]] < in[top[b]])
                    {
                        swap(a, b);
                    }
                    sum += ft1.get(in[top[a]], in[a]);
                    cnt += ft2.get(in[top[a]], in[a]);
                }
                if (in[a] > in[b])
                    swap(a, b);
                sum += ft1.get(in[a], in[b]);
                sum -= ft1.get(in[a], in[a]);
                cnt += ft2.get(in[a], in[b]);
                cnt -= ft2.get(in[a], in[a]);
                if (sum <= s)
                {
                    ans[i] = y;
                    num[i] = cnt;
                    l[i] = y + 1;
                }
                else
                {
                    r[i] = y - 1;
                }
            }
        }
    }
    for (int x = 0; x < q; x++)
    {
        auto &[a, b, g, s] = query[x];
        if (num[x] > g)
        {
            cout << -1 << "\n";
        }
        else
        {
            cout << g - num[x] << "\n";
        }
    }
}

signed main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t = 1;
    // cin >> t;
    for (int x = 1; x <= t; x++)
    {
        solve();
    }
    return 0;
}
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...