Submission #1295116

#TimeUsernameProblemLanguageResultExecution timeMemory
1295116Bui_Quoc_CuongTourism (JOI23_tourism)C++20
23 / 100
5093 ms30468 KiB
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template <class A, class B>
    bool maximize(A &a, const B b) {
        if (a < b) {
            a = b;
            return true;
        } return false;
    }
template <class A, class B>
    bool minimize(A &a, const B b) {
        if(a > b) {
            a = b;
            return true;
        } return false;
    }
using pII = pair <int, int>;
using vI = vector <int>;
using vL = vector <long long>;
using pLI = pair <long long, int>;

#define BIT(mask, i) ((mask >> (i)) & 1)
#define MASK(a) (1LL<<(a))
#define FOR(i, a, b) for(int i = a; i <= (int)b; i++)
#define FORD(i, a, b) for(int i = a; i >= (int)b; i--)
#define fi first
#define se second
#define pb push_back
#define all(a) a.begin(), a.end()
#define sz(a) (int)a.size()
const int N = 3e5 + 5;
const int LG = 22;
const int S = 550;

int n, m, q;
vector <int> g[N];
int c[N];
int hTour[N], nTour[N], timeDFS, tin[N], tout[N], h[N];
int rmq[N][LG], lg[N];

struct Queries{
    int L, R, id;
    bool operator <(const Queries &e) const{    
        if(L / S != e.L / S) return L < e.L;
        if((R / S) & 1) return R < e.R;
        return R > e.R;
    }
} Q[N];

void dfs(int u, int p){
    tin[u] = ++ timeDFS;
    hTour[timeDFS] = h[u];  
    nTour[timeDFS] = u;
    for(int &v : g[u]) if(v != p){
        h[v] = h[u] + 1;
        dfs(v, u);
        hTour[++ timeDFS] = h[u];
        nTour[timeDFS] = u;
    }
}

int merge(int i, int j){
    return hTour[i] < hTour[j] ? i : j;
}

int LCA(int u, int v){
    if(tin[u] > tin[v]) swap(u, v);
    int k = lg[tin[v] - tin[u] + 1];
    int p = merge(rmq[tin[u]][k], rmq[tin[v] - (1 << k) + 1][k]);
    return nTour[p];    
}

int dist(int u, int v){
    return h[u] + h[v] - 2 * h[LCA(u, v)];
}

set <pair <int, int>> set_euler;
int l = 1, r = 0, ans[N], res = 0, cnt[N];

void add (int u) {
    cnt[tin[u]]++;
    if (cnt[tin[u]] >= 2) return;
    if (set_euler.empty()) {
        set_euler.insert(make_pair(tin[u], u));
        return;
    }   
    auto nxt = set_euler.lower_bound(make_pair(tin[u], 0));
    auto prv = nxt;
    if (nxt == set_euler.end()) {
        nxt = prev(nxt);
        prv = set_euler.begin();
    } else if (nxt == set_euler.begin()) {
        prv = set_euler.end();
        prv--;
    } else {
        prv = prev(nxt);
    }
    res-= dist (nxt -> second, prv -> second);
    res+= dist (nxt -> second, u);
    res+= dist (prv -> second, u);
    set_euler.insert(make_pair(tin[u], u));
}

void del (int u) {
    cnt[tin[u]]--;
    if (cnt[tin[u]] >= 1) return;
    if (set_euler.size() == 1) {
        set_euler.clear();
        return;
    }
    auto it = set_euler.lower_bound(make_pair(tin[u], u));
    auto prv = it, nxt = it;
    if (next(it) == set_euler.end()) {
        prv = prev(it);
        nxt = set_euler.begin();
    } else if (it == set_euler.begin()) {
        nxt = next(it);
        prv = prev(set_euler.end());
    } else {
        nxt = next(it);
        prv = prev(it);
    }
    res+= dist (nxt -> second, prv -> second);
    res-= dist (nxt -> second, u);
    res-= dist (prv -> second, u);
    set_euler.erase(make_pair(tin[u], u));
}   

void MO(int id){
    while(l > Q[id].L) add(c[-- l]);
    while(r < Q[id].R) add(c[++ r]);
    while(l < Q[id].L) del(c[l ++]);
    while(r > Q[id].R) del(c[r --]);
    ans[Q[id].id] = res;
}

void process(){
    cin >> n >> m >> q;
    for(int i = 1; i < n; i++){
        int u, v; cin >> u >> v;
        g[u].pb(v); g[v].pb(u);
    }   
    for(int i = 1; i <= m; i++){
        cin >> c[i];
    }
    dfs(1, 1);
    for(int i = 1; i <= timeDFS; i++){
        rmq[i][0] = i;
        if(i > 1) lg[i] = lg[i >> 1] + 1;
    }
    for(int j = 1; (1 << j) <= timeDFS; j++){
        for(int i = 1; i <= timeDFS; i++){
            rmq[i][j] = merge(rmq[i][j - 1], rmq[i + (1 << (j - 1))][j - 1]);
        }
    }
    FOR(i, 1, q) cin >> Q[i].L >> Q[i].R, Q[i].id = i;
    sort(Q + 1, Q + 1 + q);
    FOR(i, 1, q) MO(i);
    FOR(i, 1, q) cout << ans[i] / 2 + 1 << "\n";
}   

int main(){
    #define taskname "kieuoanh"
    if(fopen(taskname".inp", "r")){
        freopen(taskname".inp", "r", stdin); freopen(taskname".out", "w", stdout);
    }

    int tc = 1; /// cin >> tc;
    while(tc--) process();

    return 0;
}

Compilation message (stderr)

tourism.cpp: In function 'int main()':
tourism.cpp:166:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  166 |         freopen(taskname".inp", "r", stdin); freopen(taskname".out", "w", stdout);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
tourism.cpp:166:53: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  166 |         freopen(taskname".inp", "r", stdin); freopen(taskname".out", "w", stdout);
      |                                              ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...