답안 #1071062

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
1071062 2024-08-23T04:04:13 Z Whisper Tourism (JOI23_tourism) C++17
0 / 100
4890 ms 23072 KB
#include <bits/stdc++.h>

using namespace std;
using ll = long long;

//#define int long long
#define FOR(i, a, b) for (int i = (a); i <= (b); i++)
#define FORD(i, a, b) for (int i = (b); i >= (a); i --)
#define REP(i, a) for (int i = 0; i < (a); ++i)
#define REPD(i, a) for (int i = (a) - 1; i >= 0; --i)

#define MASK(i) (1LL << (i))
#define BIT(x, i) (((x) >> (i)) & 1)


constexpr ll LINF = (1ll << 60);
constexpr int INF = (1ll << 30);
constexpr int Mod = 1e9 + 7;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

/*
    Phu Trong from Nguyen Tat Thanh High School for gifted student
*/

template <class X, class Y>
    bool minimize(X &x, const Y &y){
        X eps = 1e-9;
        if (x > y + eps) {x = y; return 1;}
        return 0;
    }

template <class X, class Y>
    bool maximize(X &x, const Y &y){
        X eps = 1e-9;
        if (x + eps < y) {x = y; return 1;}
        return 0;
    }
#define MAX                     100005
#define BLOCK_SIZE              300
#define LOG                     18
#define MIN_HIGH(u, v)          (depth[u] < depth[v] ? (u) : (v))


int numNode, numQuery, numCity;
vector<int> G[MAX];
int A[MAX];

struct Queries{
    int l, r, id;
    Queries(){}
    Queries(int _l, int _r, int _id): l(_l), r(_r), id(_id){}

    bool operator < (const Queries& oth) const{
        if (l / BLOCK_SIZE != oth.l / BLOCK_SIZE) return l / BLOCK_SIZE < oth.l / BLOCK_SIZE;
        return r < oth.r;
    }
} Q[MAX];

int ans[MAX];

int tin[MAX], st[MAX << 1][LOG], depth[MAX], rev[MAX], pos[MAX << 1];
int timeDfs = 0, cnt = 0;

int lg[MAX << 1];
void pre_dfs(int u, int p = -1){
    st[++cnt][0] = u; pos[u] = cnt;
    tin[u] = ++timeDfs; rev[tin[u]] = u;

    for (int &v : G[u]) if(v ^ p){
        depth[v] = depth[u] + 1;
        pre_dfs(v, u);
        st[++cnt][0] = u;
    }
}

void build(void){
    pre_dfs(1);
    for (int k = 1; MASK(k) <= cnt; ++k){
        for (int i = 1; i + MASK(k) - 1 <= cnt; ++i){
            st[i][k] = MIN_HIGH(st[i][k - 1], st[i + MASK(k - 1)][k - 1]);
        }
    }
    for (int i = 2; i <= cnt; ++i) lg[i] = lg[i >> 1] + 1;
}
int lca(int u, int v){
    int l = pos[u], r = pos[v];
    if(l > r) swap(l, r);
    int k = lg[r - l + 1];
    return MIN_HIGH(st[l][k], st[r - MASK(k) + 1][k]);
}
int dis(int a, int b){
    return depth[a] + depth[b] - 2 * depth[lca(a, b)];
}

namespace DistanceOnTree{
    int sum = 0;
    int F[MAX * 2];
    int low_bit(int p){
        return p & (-p);
    }

    void upd(int p, int v){
        for (; p <= cnt; p += low_bit(p)){
            F[p] += v;
        }
    }

    int query(int p){
        int res = 0;
        for (; p > 0; p -= low_bit(p)) res += F[p];
        return res;
    }
    int lower_bound(int val){
        int res = 0;
        for (int i = lg[cnt]; i >= 0; --i){
            if ((res | MASK(i)) <= cnt && val > F[res | MASK(i)]){
                val -= F[res | MASK(i)];
                res |= MASK(i);
            }
        }
        return res + 1;
    }
    int size = 0;
    int get_order(int x){
        return query(x);
    }
    int find_last(void){
        return lower_bound(size);
    }
    int find_first(void){
        return lower_bound(1);
    }
    int find_by_order(int x){
        return lower_bound(x);
    }

    int next[MAX], prev[MAX];

    int res(void){
        return sum / 2 + 1;
    }
    void ins(int x){
        x = tin[x];
        if(size){
            int i = get_order(x);
            int prv = (i > 0 ? find_by_order(i) : find_last());
            int nxt = next[prv];

            sum -= dis(rev[prv], rev[nxt]);
            sum += dis(rev[prv], rev[x]);
            sum += dis(rev[nxt], rev[x]);
            next[x] = nxt; prev[x] = prv;
            next[prv] = x; prev[nxt] = x;
        }

        upd(x, 1);
        if(!size){
            prev[x] = next[x] = x;
        }
        ++size;
    }
    void eras(int x){
        x = tin[x];
        upd(x, -1);
        --size;
        if(size){
            sum += dis(rev[prev[x]], rev[next[x]]);
            sum -= dis(rev[prev[x]], rev[x]);
            sum -= dis(rev[next[x]], rev[x]);

            next[prev[x]] = next[x];
            prev[next[x]] = prev[x];
        }
    }
}
#define T       DistanceOnTree
int in[MAX];

void sub(int x){
    in[x]--;
    if(!in[x])
        T :: eras(A[x]);
}
void add(int x){
    if(!in[x])
        T :: ins(A[x]);
    in[x]++;
}
void process(void){
    cin >> numNode >> numCity >> numQuery;
    for (int i = 1; i < numNode; ++i){
        int u, v; cin >> u >> v;
        G[u].emplace_back(v);
        G[v].emplace_back(u);
    }
    for (int i = 1; i <= numCity; ++i){
        cin >> A[i];
    }

    for (int i = 1; i <= numQuery; ++i){
        cin >> Q[i].l >> Q[i].r;
        Q[i].id = i;
    }
    sort(Q + 1, Q + numQuery + 1);
    build();
    int L = 1, R = 0;
    for (int i = 1; i <= numQuery; ++i){
        while (L < Q[i].l) sub(L++);
        while (L > Q[i].l) add(--L);
        while (R < Q[i].r) add(++R);
        while (R > Q[i].r) sub(R--);
        ans[Q[i].id] = T :: res();
    }

    for (int i = 1; i <= numQuery; ++i){
        cout << ans[i] << '\n';
    }
}
signed main(){
    #define name "Whisper"
    cin.tie(nullptr) -> sync_with_stdio(false);
    //freopen(name".inp", "r", stdin);
    //freopen(name".out", "w", stdout);
    process();
    return (0 ^ 0);
}




# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 8796 KB Output is correct
2 Correct 1 ms 9060 KB Output is correct
3 Correct 1 ms 8796 KB Output is correct
4 Incorrect 2 ms 9052 KB Output isn't correct
5 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 8796 KB Output is correct
2 Correct 1 ms 9060 KB Output is correct
3 Correct 1 ms 8796 KB Output is correct
4 Incorrect 2 ms 9052 KB Output isn't correct
5 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 8796 KB Output is correct
2 Correct 2 ms 9052 KB Output is correct
3 Correct 6 ms 9048 KB Output is correct
4 Incorrect 4452 ms 23072 KB Output isn't correct
5 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 9048 KB Output is correct
2 Incorrect 35 ms 18716 KB Output isn't correct
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 9052 KB Output is correct
2 Correct 2 ms 9052 KB Output is correct
3 Correct 6 ms 9008 KB Output is correct
4 Incorrect 4890 ms 19548 KB Output isn't correct
5 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 8796 KB Output is correct
2 Correct 1 ms 9060 KB Output is correct
3 Correct 1 ms 8796 KB Output is correct
4 Incorrect 2 ms 9052 KB Output isn't correct
5 Halted 0 ms 0 KB -