Submission #1222516

#TimeUsernameProblemLanguageResultExecution timeMemory
1222516minhpkConstruction of Highway (JOI18_construction)C++20
100 / 100
1151 ms57224 KiB
#include <bits/stdc++.h> #define int long long using namespace std; int a; int t[1000005]; vector <int> z[1000005]; int sta[1000005]; int fin[1000005]; int tour; int par[100005][21]; int rev[1000005]; pair<int,int> edge[100005]; vector<int> v; vector <int> used; int fwd[1000005]; void dfs(int i,int parent){ par[i][0]=parent; tour++; sta[i]=tour; rev[tour]=i; for (auto p:z[i]){ dfs(p,i); } fin[i]=tour; } pair<int,int> f[4000005]; pair<int,int> combine(pair<int,int> a, pair<int,int> b){ if (a.first>b.first){ return a; }else{ return b; } } void update(int id,int l,int r,int pos,pair<int,int> val){ if (l==r){ f[id]=val; return; } int mid=(l+r)/2; if (pos<=mid){ update(id*2,l,mid,pos,val); }else{ update(id*2+1,mid+1,r,pos,val); } f[id]=combine(f[id*2],f[id*2+1]); } pair<int,int> get(int id,int l,int r,int x,int y){ if (x>r || y<l){ return {0LL,0LL}; } if (l>=x && y>=r){ return f[id]; } int mid=(l+r)/2; return combine( get(id*2,l,mid,x,y), get(id*2+1,mid+1,r,x,y) ); } int bit[1000005]; void reset(){ for (auto p:used){ bit[p]=0; } used.clear(); } void update(int i,int val){ i++; while (i<=a){ if (bit[i]==0){ used.push_back(i); } bit[i]+=val; i+= i&-i; } } int query(int i){ i++; int res=0; while (i>0){ res+=bit[i]; i-= i&-i; } return res; } int get(int l,int r){ if (l>r ){ return 0; } return query(r)-query(l-1); } signed main() { ios_base::sync_with_stdio(false); cin.tie(NULL); cin >> a; for (int i=1;i<=a;i++){ cin >> t[i]; v.push_back(t[i]); } sort(v.begin(),v.end()); v.erase(unique(v.begin(),v.end()),v.end()); for (int i=1;i<=a;i++){ t[i]=lower_bound(v.begin(),v.end(),t[i])-v.begin()+1; } for (int i=1;i<a;i++){ int x,y; cin >> x >> y; z[x].push_back(y); edge[i]={x,y}; } dfs(1,0); fwd[0]=1; for (int i=1;i<=20;i++){ fwd[i]=fwd[i-1]*2; } for (int j=1;j<=20;j++){ for (int i=1;i<=a;i++){ par[i][j]=par[par[i][j-1]][j-1]; } } int cnt=1; for (int i=tour;i>=1;i--){ int u=rev[i]; pair<int,int> pre={cnt,t[u]}; update(1,1,tour,sta[u],pre); cnt++; } int q=1; while (q<a){ auto [x,y]=edge[q]; int res=0; // update(t[y],1); // cout << get(1,1) << "\n"; int p=x; auto [id,preval]=get(1,1,tour,sta[p],fin[p]); // if (q==a-1){ // cout << get(1,1,tour,sta[1],fin[1]).first << get(1,1,tour,sta[1],fin[1]).second << "\n"; // } // cout << id << " " << preval << "\n"; while (p>0){ // if (q==a-1){ // cout << p << " " << id << " " << preval << "\n"; // } int p1=p; int mul=1; for (int i=20;i>=0;i--){ if (par[p1][i]==0){ continue; } pair<int,int> pre=get(1,1,tour,sta[par[p1][i]],fin[par[p1][i]]); if (pre.first==id){ mul+=fwd[i]; p1=par[p1][i]; } } int val=get(1,preval-1); // cout << p1 << " " << preval << " " << " ok" << "\n"; res+=val*mul; update(preval,mul); p=par[p1][0]; pair<int,int> pre=get(1,1,tour,sta[p],fin[p]); id=pre.first; preval=pre.second; } pair<int,int> pre={q+tour,t[y]}; // cout << y << " "; update(1,1,tour,sta[y],pre); cout << res << "\n"; reset(); q++; } return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...