답안 #1044965

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
1044965 2024-08-05T15:11:26 Z vjudge1 Construction of Highway (JOI18_construction) C++17
0 / 100
0 ms 348 KB
#include <bits/stdc++.h>
using namespace std;

#pragma GCC optimize("O3")
#define endl '\n'
#define db double
#define ll __int128
#define int long long
#define pb push_back
#define fs first
#define sd second
#define Mod long(1e9 + 7)
#define all(x) x.begin(), x.end()
#define unvisited long(-1)
#define Eps double(1e-9)
#define _for(i, n) for(int i = 0; i < (n); i++)
#define dbg(x) cout << #x ": " << x << endl;

const int Max = 1e6 + 7, Inf = 1e9 + 7;

void print(bool x) { cout << (x ? "YES" : "NO") << endl; }

string tostring (__int128 x)
{
    string ans = "";
    while(x > 0)
    {
        ans += (x % 10 + '0');
        x /= 10;
    }
    reverse(all(ans));
    return ans;
}

vector <vector<int>> v; 
vector <int> in, out, s; 

struct SegmentTree1
{
    vector <int> tree; int l;

    void update(int k, int x){
        k += (l - 1)+1; tree[k] = x;
        for(k /= 2; k > 0; k /= 2){
            tree[k] = max(tree[2*k], tree[2*k+1]); 
        }
    } 

    int query(int node, int x, int y, int s, int e){
        if(s > y || e < x) return 0; 
        if(s >= x && e <= y){
            return tree[node];
        }
        int mid = (s + e) / 2;
        return max(query(node*2, x, y, s, mid),
            query(node*2+1, x, y, mid+1, e)); 
    }

    int query(int x, int y){
        return query(1, x+1, y+1, 1, l); 
    }

    SegmentTree1 (int n)
    {
        for(l = 1; l < n; l *= 2);
        tree.assign(2*l+7, 0); 
    }
};

struct SegmentTree2
{
    vector <int> tree; int l;

    void update(int k, int x){
        k += (l - 1) + 1; tree[k] = x; 
        for(k /= 2; k > 0; k /= 2){
            tree[k] = tree[2*k] + tree[2*k+1]; 
        }
    } 

    int query(int node, int x, int y, int s, int e){
        if(s > y || e < x) return 0; 
        if(s >= x && e <= y){
            return tree[node];
        }
        int mid = (s + e) / 2;
        return query(node*2, x, y, s, mid) +
            query(node*2+1, x, y, mid+1, e); 
    }

    int query(int x, int y){
        return query(1, x+1, y+1, 1, l); 
    }

    SegmentTree2 (int n)
    {
        for(l = 1; l < n; l *= 2);
        tree.assign(2*l+7, 0); 
    }
};

void dfs(int node)
{
    in[node] = s.size(); 
    s.push_back(node);
    for(auto& u : v[node]){
        dfs(u);  
    }
    out[node] = s.size(); 
    s.push_back(node); 
}

vector <int> cmp(vector <int> c){
    vector <pair<int, int>> t; 
    _for(i, c.size()) t.push_back({ c[i], i });
    sort(all(t));  
    _for(i, c.size()) c[t[i].sd] = i;
    return c; 
} 

void solve()
{
    int n; cin >> n; 
    vector <int> c(n+1), d(n+1); 
    _for(i, n) cin >> c[i+1];
    c = cmp(c); 
    vector <pair<int, int>> edge(n-1); 
    v.assign(n+1, vector <int> ()); 
    for(auto& u : edge){
        cin >> u.fs >> u.sd; 
        v[u.fs].pb(u.sd); //v[u.sd].pb(u.fs); 
    }

    in.assign(2*n+7, 0); 
    out.assign(2*n+7, 0);
    dfs(1);

    vector <vector<int>> p(n+1, vector <int> (21, 0)); 
    SegmentTree1 St1(2*n+7); SegmentTree2 St2(2*n+7);

    _for(i, n-1)
    {
        vector <pair<int, int>> f; 
        int ans = 0, x = edge[i].fs;

        if(i == 0){
            ans = (c[edge[i].fs] > c[edge[i].sd]);
        }

        while (x != 0)
        { 
            f.push_back({ 1, St1.query(in[x], out[x]) });
            for(int j = 20; j >= 0; j--) if(p[x][j] != 0){
                int y = p[x][j]; 
                if(St1.query(in[y], out[y]) == f.back().sd){
                    x = y;
                    f.back().fs += (1LL << j);
                }
            }
            x = p[x][0]; 
        } 

        p[edge[i].sd][0] = edge[i].fs; 
        for(int j = 1; j <= 20; j++){
            p[edge[i].sd][j] = p[p[edge[i].sd][j-1]][j-1];
        }

        reverse(all(f)); 

        for(auto& u : f){
            ans = ans + u.fs * (St2.query(c[edge[u.sd].sd]+1, n+2)); 
            St2.update(c[edge[u.sd].sd], u.fs); 
        }

        for(auto& u : f){
            St2.update(c[edge[u.sd].sd], 0); 
        }

        St1.update(in[edge[i].sd], i);

        cout << ans << endl; 
    }
}

int32_t main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);

    int Q = 1; //cin >> Q;

    while (Q--)
    {
        solve();
    }

    return 0;
}

Compilation message

construction.cpp: In function 'std::vector<long long int> cmp(std::vector<long long int>)':
construction.cpp:16:37: 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]
   16 | #define _for(i, n) for(int i = 0; i < (n); i++)
      |                                     ^
construction.cpp:115:5: note: in expansion of macro '_for'
  115 |     _for(i, c.size()) t.push_back({ c[i], i });
      |     ^~~~
construction.cpp:16:37: 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]
   16 | #define _for(i, n) for(int i = 0; i < (n); i++)
      |                                     ^
construction.cpp:117:5: note: in expansion of macro '_for'
  117 |     _for(i, c.size()) c[t[i].sd] = i;
      |     ^~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 348 KB Output is correct
2 Incorrect 0 ms 348 KB Output isn't correct
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 348 KB Output is correct
2 Incorrect 0 ms 348 KB Output isn't correct
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 348 KB Output is correct
2 Incorrect 0 ms 348 KB Output isn't correct
3 Halted 0 ms 0 KB -