제출 #44000

#제출 시각아이디문제언어결과실행 시간메모리
44000zscoderConstruction of Highway (JOI18_construction)C++17
100 / 100
542 ms187244 KiB
#include <bits/stdc++.h> #include <ext/pb_ds/assoc_container.hpp> #include <ext/pb_ds/tree_policy.hpp> using namespace std; using namespace __gnu_pbds; #define fi first #define se second #define mp make_pair #define pb push_back #define fbo find_by_order #define ook order_of_key typedef long long ll; typedef pair<int,int> ii; typedef vector<int> vi; typedef long double ld; typedef tree<ll, null_type, less<ll>, rb_tree_tag, tree_order_statistics_node_update> pbds; typedef set<ll>::iterator sit; typedef map<ll,ll>::iterator mit; int a[111111]; int sz[111111]; int in[111111]; int rin[111111]; int t; int out[111111]; deque<ii> chain[111111]; //heavy chain starting at vertex u int nxt[111111]; vi adj[111111]; int par[111111]; int h[111111]; void addtochain(int u, int v) { if(chain[u].empty()) chain[u].pb(mp(v,1)); else if(chain[u].back().fi==v) chain[u].back().se++; else chain[u].pb(mp(v,1)); } void dfs_sz(int v = 0) { sz[v] = 1; for(auto &u: adj[v]) { par[u] = v; h[u] = h[v] + 1; dfs_sz(u); sz[v] += sz[u]; if(sz[u] > sz[adj[v][0]]) swap(u, adj[v][0]); } } void dfs_hld(int v = 0) { in[v] = t++; rin[in[v]] = v; for(auto u: adj[v]) { nxt[u] = (u == adj[v][0] ? nxt[v] : u); dfs_hld(u); } out[v] = t; } int fen[111111]; int N; void init(int n) { N=n; for(int i=0;i<=N;i++) fen[i]=0; } void update(int pos, int v) { pos++; for(;pos<=N;pos+=(pos&(-pos))) { fen[pos]+=v; } } int query(int pos) { pos++; int sum=0; for(;pos;pos-=(pos&(-pos))) { sum+=fen[pos]; } return sum; } ll calc_path(int u) { vector<ii> V; vi coord; while(u!=-1) { int nu = nxt[u]; int siz = h[u] - h[nu] + 1; vector<ii> tst; //cerr<<"CHAIN : "<<u<<' '<<nu<<'\n'; for(int i=0;i<chain[nu].size();i++) { int cnt = chain[nu][i].fi; int v = chain[nu][i].se; if(cnt<=siz) { tst.pb(mp(cnt,v)); siz-=cnt; } else { tst.pb(mp(siz,v)); break; } } for(int i=int(tst.size())-1;i>=0;i--) { V.pb(tst[i]); coord.pb(tst[i].se); } u=par[nu]; } reverse(V.begin(),V.end()); sort(coord.begin(),coord.end()); coord.erase(unique(coord.begin(),coord.end()),coord.end()); //cerr<<coord.size()<<'\n'; init(int(coord.size())); ll ans = 0; ll tot = 0; for(ii x:V) { x.se = lower_bound(coord.begin(),coord.end(),x.se)-coord.begin(); ans += x.fi*(tot - query(x.se)); //cerr<<x.fi<<' '<<x.se<<'\n'; tot+=x.fi; update(x.se, x.fi); } //cerr<<'\n'; return ans; } void addedge(int u, int v) { while(u!=-1) { int nu = nxt[u]; int siz = h[u] - h[nu] + 1; while(chain[nu].size()>0) { int cnt = chain[nu][0].fi; if(cnt<=siz) { chain[nu].pop_front(); siz-=cnt; } else { chain[nu].front().fi -= siz; break; } } chain[nu].push_front(mp(h[u]-h[nu]+1, v)); u=par[nu]; } } int main() { ios_base::sync_with_stdio(0); cin.tie(0); int n; cin>>n; for(int i=0;i<n;i++) cin>>a[i]; nxt[0] = 0; addtochain(0,a[0]); vector<ii> edges; par[0]=-1; for(int i=0;i<n-1;i++) { int u,v; cin>>u>>v; u--; v--; adj[u].pb(v); edges.pb(mp(u,v)); } dfs_sz(); dfs_hld(); for(int i=0;i<n-1;i++) { cout<<calc_path(edges[i].fi)<<'\n'; addedge(edges[i].se, a[edges[i].se]); //calc_path(edges[i].fi, edges[i].se); } }

컴파일 시 표준 에러 (stderr) 메시지

construction.cpp: In function 'll calc_path(int)':
construction.cpp:105:16: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for(int i=0;i<chain[nu].size();i++)
               ~^~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...