답안 #1037708

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
1037708 2024-07-29T07:08:13 Z 정민찬(#10982) Tourism (JOI23_tourism) C++17
0 / 100
3295 ms 1048576 KB
#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<ll,ll> pll;

const int inf = 2e9;

int N, M, Q;
vector<int> adj[100010];
int C[100010];
vector<int> s[100010];
int L[100010];
int R[100010];
int ans[100010];

int chk[100010];
int sz[100010];

int getSize(int x, int p) {
    sz[x] = 1;
    for (auto &y : adj[x]) {
        if (y == p || chk[y]) continue;
        sz[x] += getSize(y, x);
    }
    return sz[x];
}

int getCent(int x, int p, int cap) {
    for (auto &y : adj[x]) {
        if (y == p || chk[y]) continue;
        if (sz[y] * 2 > cap) return getCent(y, x, cap);
    }
    return x;
}

struct Fenwick{
    vector<int> tree;
    void init(int n) {
        tree.assign(n+1, 0);
    }
    void upd(int i, int v, int n) {
        while (i <= n) {
            tree[i] += v;
            i += i & -i;
        }
    }
    int qry(int i) {
        int ret = 0;
        while (i) {
            ret += tree[i];
            i -= i & -i;
        }
        return ret;
    }
    int qry(int l, int r) {
        return qry(r) - qry(l-1);
    }
};

struct MaxSegmentTree{
    vector<pair<int,int>> tree;
    void init(int n) {
        int sz = 1 << __lg(n-1) + 2;
        tree.resize(sz);
        build(1, 1, n);
    }
    void build(int node, int s, int e) {
        if (s == e) {
            tree[node] = {-inf, s};
            return;
        }
        int mid = s + e >> 1;
        build(node*2, s, mid);
        build(node*2+1, mid+1, e);
        tree[node] = max(tree[node*2], tree[node*2+1]);
    }
    void update(int node, int s, int e, int tar, int val, int num = -1) {
        if (s > tar || tar > e) return;
        if (s == e) {
            if (num == -1) num = s;
            tree[node] = {val, num};
            return;
        }
        int mid = s + e >> 1;
        update(node*2, s, mid, tar, val, num);
        update(node*2+1, mid+1, e, tar, val, num);
        tree[node] = max(tree[node*2], tree[node*2+1]);
    }
    pair<int,int> query(int node, int s, int e, int l, int r) {
        if (l > e || s > r) return {-inf, -1};
        if (l <= s && e <= r) return tree[node];
        int mid = s + e >> 1;
        return max(query(node*2, s, mid, l, r), query(node*2+1, mid+1, e, l, r));
    }
};

Fenwick seg;
MaxSegmentTree mxs, mns;

vector<int> D;

int Idx(int v) {
    return lower_bound(D.begin(), D.end(), v) - D.begin() + 1;
}

void dfs(int x, int p) {
    for (auto &k : s[x]) {
        D.push_back(k);
    }
    for (auto &y : adj[x]) {
        if (y == p || chk[y]) continue;
        dfs(y, x);
    }
}

void dfs2(int x, int p, int r) {
    for (auto &k : s[x]) {
        int idx = Idx(k);
        mxs.update(1, 1, D.size(), idx, r);
        mns.update(1, 1, D.size(), idx, -r);
    }
    for (auto &y : adj[x]) {
        if (y == p || chk[y]) continue;
        dfs2(y, x, r);
    }
}

int getSize2(int x, int p) {
    sz[x] = s[x].size();
    for (auto &y : adj[x]) {
        if (y == p || chk[y]) continue;
        sz[x] += getSize2(y, x);
    }
    return sz[x];
}

set<int> ss[100010];
int id[100010];
int pv;
vector<pair<int,int>> save[100010];

void my_ins(int i, int k, int cnt, int x) {
    /*auto rit = ss[i].lower_bound(k);
    if (rit != ss[i].end()) {
        save[k+1].push_back({*rit, cnt});
    }
    if (rit != ss[i].begin()) {
        auto lit = prev(rit);
        save[*lit+1].push_back({k, cnt});
        if (rit != ss[i].end()) {
            save[*lit+1].push_back({*rit, -cnt});
        }
    }*/
    ss[i].insert(k);
}

int dfs4(int x, int p, int cnt) {
    int mxsz = -1, ch = -1;
    for (auto &y : adj[x]) {
        if (y == p || chk[y]) continue;
        if (sz[y] > mxsz) {
            mxsz = sz[y];
            ch = y;
        }
    }
    if (ch == -1) {
        id[x] = pv ++;
        int p = 0;
        ss[id[x]].insert(0);
        for (auto &k : s[x]) {
            ss[id[x]].insert(Idx(k));
            save[p+1].push_back({Idx(k), 1});
            p = Idx(k);
        }
        return id[x];
    }
    else {
        id[x] = dfs4(ch, x, cnt + 1);
        for (auto &y : adj[x]) {
            if (y == p || y == ch || chk[y]) continue;
            int z = dfs4(y, x, 1);
            for (auto &k : ss[z]) {
                if (k == 0) continue;
                my_ins(id[x], Idx(k), cnt, x);
            }
        }
        for (auto &k : s[x]) {
            my_ins(id[x], Idx(k), cnt, x);
        }
        int p = 0;
        for (auto &k : ss[id[x]]) {
            if (k == 0) continue;
            save[p+1].push_back({k, 1});
            p = k;
        }
        return id[x];
    }
}

void dnc(int x, vector<int> qrs) {
    if (qrs.empty()) return;
    x = getCent(x, -1, getSize(x, -1));
    D.clear();
    dfs(x, -1);
    sort(D.begin(), D.end());
    mxs.init(D.size()); mns.init(D.size());
    for (int i=0; i<adj[x].size(); i++) {
        int y = adj[x][i];
        if (chk[y]) continue;
        dfs2(y, x, i);
    }
    for (auto &k : s[x]) {
        int idx = Idx(k);
        mxs.update(1, 1, D.size(), idx, -1);
        mns.update(1, 1, D.size(), idx, 1);
    }
    vector<int> curq;
    vector<int> nxtq[adj[x].size()];
    for (auto &i : qrs) {
        int li = Idx(L[i]), ri = Idx(R[i]);
        int ret1 = mxs.query(1, 1, D.size(), li, ri).first;
        int ret2 = -mns.query(1, 1, D.size(), li, ri).first;
        if (ret1 == ret2 && ret1 != -1) {
            nxtq[ret1].push_back(i);
        }
        else {
            curq.push_back(i);
        }
    }
    getSize2(x, -1);
    pv = 0;
    dfs4(x, -1, 0);
    for (int i=0; i<pv; i++) {
        ss[i].clear();
    }
    seg.init(D.size());
    sort(curq.begin(), curq.end(), [&] (int &u, int &v) { return L[u] < L[v]; });
    int j = 0;
    for (int i=1; i<=D.size(); i++) {
        for (auto &[pos, v] : save[i]) {
            seg.upd(pos, v, D.size());
        }
        while (j < curq.size() && L[curq[j]] == D[i-1]) {
            ans[curq[j]] = seg.qry(Idx(L[curq[j]]), Idx(R[curq[j]]));
            j ++;
        }
    }
    for (int i=0; i<=D.size() + 2; i++) {
        save[i].clear();
    }
    chk[x] = 1;
    for (int i=0; i<adj[x].size(); i++) {
        int y = adj[x][i];
        if (chk[y]) continue;
        dnc(y, nxtq[i]);
    }
}

int main() {
    ios_base :: sync_with_stdio(false); cin.tie(NULL);
    cin >> N >> M >> Q;
    for (int i=0; i<N-1; i++) {
        int u, v;
        cin >> u >> v;
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    for (int i=1; i<=M; i++) {
        cin >> C[i];
        s[C[i]].push_back(i);
    }
    for (int i=1; i<=Q; i++) {
        cin >> L[i] >> R[i];
    }
    vector<int> Sum(N+1, 0);
    for (int i=1; i<=N; i++) {
        sort(s[i].begin(), s[i].end());
        Sum[i] = Sum[i-1] + s[i].size();
    }
    vector<int> initq(Q);
    iota(initq.begin(), initq.end(), 1);
    dnc(1, initq);
    for (int i=1; i<=Q; i++) {
        cout << ans[i] << '\n';
    }
}

Compilation message

tourism.cpp: In member function 'void MaxSegmentTree::init(int)':
tourism.cpp:65:33: warning: suggest parentheses around '+' inside '<<' [-Wparentheses]
   65 |         int sz = 1 << __lg(n-1) + 2;
      |                       ~~~~~~~~~~^~~
tourism.cpp: In member function 'void MaxSegmentTree::build(int, int, int)':
tourism.cpp:74:21: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   74 |         int mid = s + e >> 1;
      |                   ~~^~~
tourism.cpp: In member function 'void MaxSegmentTree::update(int, int, int, int, int, int)':
tourism.cpp:86:21: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   86 |         int mid = s + e >> 1;
      |                   ~~^~~
tourism.cpp: In member function 'std::pair<int, int> MaxSegmentTree::query(int, int, int, int, int)':
tourism.cpp:94:21: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   94 |         int mid = s + e >> 1;
      |                   ~~^~~
tourism.cpp: In function 'void dnc(int, std::vector<int>)':
tourism.cpp:209:20: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  209 |     for (int i=0; i<adj[x].size(); i++) {
      |                   ~^~~~~~~~~~~~~~
tourism.cpp:241:20: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  241 |     for (int i=1; i<=D.size(); i++) {
      |                   ~^~~~~~~~~~
tourism.cpp:245:18: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  245 |         while (j < curq.size() && L[curq[j]] == D[i-1]) {
      |                ~~^~~~~~~~~~~~~
tourism.cpp:250:20: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  250 |     for (int i=0; i<=D.size() + 2; i++) {
      |                   ~^~~~~~~~~~~~~~
tourism.cpp:254:20: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  254 |     for (int i=0; i<adj[x].size(); i++) {
      |                   ~^~~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 3 ms 14684 KB Output is correct
2 Correct 2 ms 14940 KB Output is correct
3 Correct 3 ms 14684 KB Output is correct
4 Incorrect 3 ms 14940 KB Output isn't correct
5 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 3 ms 14684 KB Output is correct
2 Correct 2 ms 14940 KB Output is correct
3 Correct 3 ms 14684 KB Output is correct
4 Incorrect 3 ms 14940 KB Output isn't correct
5 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 3 ms 14936 KB Output is correct
2 Correct 4 ms 14940 KB Output is correct
3 Correct 5 ms 15196 KB Output is correct
4 Runtime error 3295 ms 1048576 KB Execution killed with signal 9
5 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 3 ms 14680 KB Output is correct
2 Correct 166 ms 41156 KB Output is correct
3 Correct 258 ms 57544 KB Output is correct
4 Correct 200 ms 49392 KB Output is correct
5 Correct 333 ms 65116 KB Output is correct
6 Correct 336 ms 65480 KB Output is correct
7 Correct 357 ms 65324 KB Output is correct
8 Correct 305 ms 63940 KB Output is correct
9 Correct 346 ms 65764 KB Output is correct
10 Correct 312 ms 65480 KB Output is correct
11 Correct 328 ms 64096 KB Output is correct
12 Correct 352 ms 66248 KB Output is correct
13 Incorrect 524 ms 64688 KB Output isn't correct
14 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 3 ms 14684 KB Output is correct
2 Correct 3 ms 14940 KB Output is correct
3 Correct 5 ms 15020 KB Output is correct
4 Incorrect 565 ms 69204 KB Output isn't correct
5 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 3 ms 14684 KB Output is correct
2 Correct 2 ms 14940 KB Output is correct
3 Correct 3 ms 14684 KB Output is correct
4 Incorrect 3 ms 14940 KB Output isn't correct
5 Halted 0 ms 0 KB -