제출 #934626

#제출 시각아이디문제언어결과실행 시간메모리
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...