Submission #934626

#TimeUsernameProblemLanguageResultExecution timeMemory
934626velislavgarkovTourism (JOI23_tourism)C++14
10 / 100
4128 ms83580 KiB
#include <iostream>
#include <algorithm>
#include <vector>
#include <stack>
using namespace std;
#define endl '\n'
const int MAXN=1e5+10;
const int BUCK=450;
struct Query {
    int l, r;
    int ind;
    bool friend operator < (Query a, Query b) {
        return a.r>b.r;
    }
};
struct Sight {
    int x;
    int ind;
    bool friend operator < (Sight a, Sight b) {
        return a.x<b.x;
    }
};
Sight c[MAXN];
Query que[MAXN];
vector <int> v[MAXN];
vector <int> arr, isl;
int fe[MAXN], le[MAXN], in[MAXN], dep[MAXN];
int sp[2*MAXN][20], stepen[2*MAXN];
stack <pair <int*,int> > st;
int pos[MAXN], lef[MAXN], ri[MAXN], res;
vector <int> sq[MAXN/BUCK];
int ans[MAXN];
int n, m, q, cnt;
bool cmpi(int a, int b) {
    return in[a]<in[b];
}
bool cmpc(Sight a, Sight b) {
    return in[a.x]<in[b.x];
}
void dfs(int x, int p) {
    in[x]=cnt;
    cnt++;
    fe[x]=arr.size();
    for (auto i:v[x]) {
        if (i==p) continue;
        arr.push_back(x);
        dep[i]=dep[x]+1;
        dfs(i,x);
    }
    le[x]=arr.size();
    arr.push_back(x);
}
void sparce_table() {
    int kn=arr.size();
    for (int i=0;i<kn;i++) sp[i][0]=arr[i];
    for (int i=1;(1<<i)<=kn;i++) {
        for (int j=0;j+(1<<i)-1<kn;j++) {
            int i1, i2;
            i1=sp[j][i-1];
            i2=sp[j + (1 << (i-1))][i-1];
            if (dep[i1]<dep[i2]) sp[j][i]=i1;
            else sp[j][i]=i2;
        }
    }
    int st=0;
    for (int i=1;i<=kn;i++) {
        if ((1 << (st+1))<i) st++;
        stepen[i]=st;
    }
}
int lca(int l, int r) {
    int st=stepen[r-l+1];
    int i1, i2;
    i1=sp[l][st];
    i2=sp[r - (1<<st)+1][st];
    if (dep[i1]<dep[i2]) return i1;
    return i2;
}
int getdist(int a, int b) {
    if (in[a]>in[b]) swap(a,b);
    return dep[a]+dep[b]-2*dep[lca(fe[a],fe[b])];
}
void undo() {
    for (int times=0;times<3;times++) {
        (*st.top().first)=st.top().second;
        st.pop();
    }
}
void remove(int i) {
    i=pos[i];
    st.push({&res,res});
    st.push({ri+lef[i],ri[lef[i]]});
    st.push({lef+ri[i],lef[ri[i]]});

    res-=getdist(c[lef[i]].x,c[i].x);
    res-=getdist(c[i].x,c[ri[i]].x);
    res+=getdist(c[lef[i]].x,c[ri[i]].x);
    ri[lef[i]]=ri[i];
    lef[ri[i]]=lef[i];
}
int main () {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int a, b;
    cin >> n >> m >> q;
    for (int i=0;i<n-1;i++) {
        cin >> a >> b;
        v[a].push_back(b);
        v[b].push_back(a);
    }
    cnt=1;
    dfs(1,-1);
    sparce_table();
    for (int i=0;i<m;i++) {
        cin >> c[i].x;
        c[i].ind=i;
    }
    sort(c,c+m,cmpc);
    for (int i=0;i<m;i++) {
        pos[c[i].ind]=i;
        lef[i]=i-1;
        ri[i]=i+1;
        res+=getdist(c[i].x,c[(i+1)%m].x);
    }
    lef[0]=m-1;
    ri[m-1]=0;
    for (int i=0;i<q;i++) {
        cin >> que[i].l >> que[i].r;
        que[i].l--; que[i].r--;
        que[i].ind=i;
    }
    sort(que,que+q);
    for (int i=0;i<q;i++) {
        if (que[i].l==que[i].r) ans[que[i].ind]=1;
        else sq[que[i].l/BUCK].push_back(i);
    }
    int curl, curr;
    for (int i=0;i*BUCK<m;i++) {
        curr=m-1;
        for (auto j:sq[i]) {
            while (curr>que[j].r) {
                remove(curr);
                curr--;
            }
            curl=i*BUCK;
            while (curl<que[j].l) {
                remove(curl);
                curl++;
            }
            ans[que[j].ind]=res/2+1;
            while (curl>i*BUCK) {
                undo();
                curl--;
            }
        }
        while (curr<m-1) {
            curr++;
            undo();
        }
        if ((i+1)*BUCK<m) {
            for (int j=i*BUCK;j<(i+1)*BUCK;j++) remove(j);
        }
    }
    for (int i=0;i<q;i++) cout << ans[i] << endl;
    return 0;
}
#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...