제출 #908613

#제출 시각아이디문제언어결과실행 시간메모리
908613vjudge1Two Currencies (JOI23_currencies)C++17
38 / 100
544 ms53132 KiB
#pragma GCC optimize("unroll-loops")
#pragma gcc optimize("Ofast")
#pragma GCC optimization("Ofast")
#pragma optimize(Ofast)
#include <bits/stdc++.h>
using namespace std;
 
#define int long long
#define str string
#define fastio ios::sync_with_stdio(0), cin.tie(0);
#define fs first
#define ss second
#define endl '\n'
#define all(x) (x).begin(), (x).end()
#define len(x) x.size()
 
#define print(a)          \
    for (auto &x : a)     \
        cout << x << " "; \
    cout << endl;
 
#define printmp(a)    \
    for (auto &x : a) \
        cout << x.fs << " " << x.ss << endl;
 
const int mod = 998244353;
 
vector<vector<pair<int, int>>> tree;
vector<int> degree, c;
vector<pair<int, int>> p;
vector<vector<int>> k;
bitset<2001> used;
 
void dfs(int n){
    used[n] = 1;
    for(auto &x : tree[n]){
        if(!used[x.fs]){
            p[x.fs] = {n, x.ss};
            degree[x.fs] = degree[n] + 1;
            dfs(x.fs);
        }
    }
}
 
void dfs(int s, int t){
    if(s == t)
        return;
    if(degree[s] >= degree[t]){
        for(auto x : k[p[s].ss])
            c.push_back(x);
        dfs(p[s].fs, t);
    }
    else{
        for(auto x : k[p[t].ss])
            c.push_back(x);
        dfs(s, p[t].fs);
    }
}
 
struct Lowest_Common_Ancestor
{
    vector<vector<int>> LCA, Count;
    vector<int> Degree;
    int ans = 0;
 
    void dfs(int u, int p, int y)
    {
        LCA[u][0] = p;
        if(k[y].size() > 0)
            Count[u][0] = k[y].size() * k[y][0];
        for (auto &x : tree[u])
        {
            if (x.fs != p)
            {
                Degree[x.fs] = Degree[u] + 1;
                dfs(x.fs, u, x.ss);
            }
        }
    }
 
    Lowest_Common_Ancestor()
    {
        LCA.resize(tree.size(), vector<int>((int)(log2(tree.size())) + 1));
        Count.resize(tree.size(), vector<int>((int)(log2(tree.size())) + 1));
        Degree.resize(tree.size(), 1);
 
        dfs(1, -1, 0);
 
        for (int j = 1; j < LCA[0].size(); j++)
            for (int i = 1; i <= tree.size() - 1; i++)
                if (LCA[i][j - 1] == -1)
                    LCA[i][j] = -1, Count[i][j] = Count[i][j - 1];
                else
                    LCA[i][j] = LCA[LCA[i][j - 1]][j - 1], Count[i][j] = Count[i][j - 1] + Count[LCA[i][j - 1]][j - 1];
    }
 
    void binary_shifting(int &X, int k)
    {
        for (int i = LCA[X].size(); i >= 0; i--)
        {
            if (k >= (1 << i))
            {
                ans += Count[X][i];
                X = LCA[X][i];
                k -= (1 << i);
            }
        }
    }
 
    int lca(int X, int Y)
    {
        ans = 0;
        if (Degree[X] < Degree[Y])
            swap(X, Y);
        if (Degree[X] != Degree[Y])
            binary_shifting(X, Degree[X] - Degree[Y]);
        int k = LCA[0].size() - 1;
        while (X != Y)
        {
            int l = 0, r = k;
            while (l < r)
            {
                int m = (l + r + 1) >> 1;
                if (LCA[X][m] == LCA[Y][m])
                    r = m - 1;
                else
                    l = m;
            }
            ans += Count[X][l] + Count[Y][l];
            X = LCA[X][l];
            Y = LCA[Y][l];
            k = l;
        }
        return ans;
    }
};
 
void solve(){
    int n, m, q;
    cin >> n >> m >> q;
    tree.resize(n + 1);
    for(int i = 0; i < n - 1; i ++){
        int u, v;
        cin >> u >> v;
        tree[u].push_back({v, i + 1});
        tree[v].push_back({u, i + 1});
    }
    k.resize(n);
    int w;
    for(int i = 0; i < m; i ++){
        int u, v;
        cin >> u >> v;
        k[u].push_back(v);
        w = v;
    }
    if(n <= 2000 and m <= 2000 and q <= 2000){
        degree.resize(n + 1);
        p.resize(n + 1);
        dfs(1);
        while(q --){
            int s, t, x, y;
            cin >> s >> t >> x >> y;
            dfs(s, t);
            sort(all(c));
            for(int j = 0; j < c.size(); j ++){
                if(c[j] <= y)
                    y -= c[j];
                else{
                    x -= c.size() - j;
                    break;
                }
            }
            if(x >= 0)
                cout << x;
            else
                cout << -1;
            cout << endl;
            c.clear();
        }
    }
    else{
        Lowest_Common_Ancestor l;
        while(q --){
            int s, t, x, y;
            cin >> s >> t >> x >> y;
            int p = y / w, q = l.lca(s, t) / w;
            q -= min(q, p);
            x -= q;
            if(x >= 0)
                cout << x << endl;
            else
                cout << -1 << endl;
        }
    }
}
 
signed main()
{
    fastio int t = 1;
    // cin >> t;
    while (t--)
    {
        solve();
        cout << endl;
    }
}
//

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

currencies.cpp:2: warning: ignoring '#pragma gcc optimize' [-Wunknown-pragmas]
    2 | #pragma gcc optimize("Ofast")
      | 
currencies.cpp:3: warning: ignoring '#pragma GCC optimization' [-Wunknown-pragmas]
    3 | #pragma GCC optimization("Ofast")
      | 
currencies.cpp:4: warning: ignoring '#pragma optimize ' [-Wunknown-pragmas]
    4 | #pragma optimize(Ofast)
      | 
currencies.cpp: In constructor 'Lowest_Common_Ancestor::Lowest_Common_Ancestor()':
currencies.cpp:89:27: 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]
   89 |         for (int j = 1; j < LCA[0].size(); j++)
      |                         ~~^~~~~~~~~~~~~~~
currencies.cpp:90:31: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<std::vector<std::pair<long long int, long long int> > >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   90 |             for (int i = 1; i <= tree.size() - 1; i++)
      |                             ~~^~~~~~~~~~~~~~~~~~
currencies.cpp: In function 'void solve()':
currencies.cpp:165:30: 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]
  165 |             for(int j = 0; j < c.size(); j ++){
      |                            ~~^~~~~~~~~~
currencies.cpp:186:44: warning: 'w' may be used uninitialized in this function [-Wmaybe-uninitialized]
  186 |             int p = y / w, q = l.lca(s, t) / w;
      |                                ~~~~~~~~~~~~^~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...