Submission #490912

#TimeUsernameProblemLanguageResultExecution timeMemory
490912nafis_shifatConstruction of Highway (JOI18_construction)C++17
100 / 100
288 ms22168 KiB
#include<bits/stdc++.h> #define ll long long #define pii pair<int,int> using namespace std; const int mxn=1e5+5; const int inf=1e9; int n, c[mxn]; vector<int> adj[mxn]; int U[mxn], V[mxn]; int chainNo = 1; int ptr = 1; int parent[mxn]; int chainHead[mxn]; int chainInd[mxn]; int posInBase[mxn]; int subsize[mxn]; int chainLen[mxn] = {}; vector<pii> con[mxn]; struct BIT { int bit[mxn] = {}; vector<pii> ups; void update(int p,int v, bool rem = true) { if(p <= 0) return; if(rem) ups.emplace_back(p, v); for(;p<mxn;p+=p&-p) bit[p] += v; } int query(int p) { int r=0; for(;p>0;p-=p&-p) r += bit[p]; return r; } void clear() { while(!ups.empty()) { update(ups.back().first, -ups.back().second, false); ups.pop_back(); } } } bt; void dfs(int u, int prev) { subsize[u] = 1; for(int v : adj[u]) { if(v == prev) continue; parent[v] = u; dfs(v, u); subsize[u] += subsize[v]; } } void HLD(int curNode, int prev) { if(chainHead[chainNo] == -1) { chainHead[chainNo] = curNode; } chainLen[chainNo]++; chainInd[curNode] = chainNo; posInBase[curNode] = ptr++; int sc = -1; for(int i = 0; i < adj[curNode].size(); i++) if(adj[curNode][i] != prev){ if(sc == -1 || subsize[sc] < subsize[adj[curNode][i]]) { sc = adj[curNode][i]; } } if(sc != -1) { HLD(sc, curNode); } for(int i=0; i < adj[curNode].size(); i++) if(adj[curNode][i] != prev) { if(sc != adj[curNode][i]) { chainNo++; HLD(adj[curNode][i], curNode); } } } ll get(int u, int v, int x) { int dn = 0; int len = posInBase[v] - posInBase[u] + 1; int id = chainInd[u]; ll ans = 0; vector<pii> prc; while(dn < len) { if(dn + con[id].back().first > len) { pii lst = con[id].back(); con[id].pop_back(); int dif = len - dn; prc.emplace_back(dif, lst.second); dn = len; con[id].push_back({lst.first - dif, lst.second}); break; } assert(!con[id].empty()); pii lst = con[id].back(); con[id].pop_back(); prc.emplace_back(lst.first, lst.second); dn += lst.first; } con[id].push_back({len, x}); while(!prc.empty()) { ans += 1ll * prc.back().first * bt.query(prc.back().second - 1); bt.update(prc.back().second, prc.back().first); prc.pop_back(); } return ans; } ll query_up(int u, int x) { if(u == 1) return 0; int uchain, ans = 0; while(u > 0) { uchain = chainInd[u]; if(uchain == 1) { ans += get(1, u, x); break; } ans += get(chainHead[uchain], u, x); u = chainHead[uchain]; u = parent[u]; } return ans; } int main() { memset(chainHead, -1, sizeof chainHead); cin >> n; vector<int> vv; for(int i = 1; i <= n; i++) { scanf("%d", &c[i]); vv.push_back(c[i]); } sort(vv.begin(), vv.end()); vv.erase(unique(vv.begin(), vv.end()), vv.end()); for(int i = 1; i <= n; i++) { c[i] = lower_bound(vv.begin(), vv.end(), c[i]) - vv.begin() + 1; } for(int i = 1; i < n; i++) { scanf("%d%d", &U[i], &V[i]); adj[U[i]].push_back(V[i]); adj[V[i]].push_back(U[i]); } dfs(1, -1); HLD(1, -1); for(int i = 1; i <= n && chainHead[i] != -1; i++) { con[i].emplace_back(chainLen[i], -1); } for(int i = 1; i < n; i++) { cout<<query_up(V[i], c[V[i]])<<"\n"; bt.clear(); } }

Compilation message (stderr)

construction.cpp: In function 'void HLD(int, int)':
construction.cpp:75:19: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   75 |  for(int i = 0; i < adj[curNode].size(); i++) if(adj[curNode][i] != prev){
      |                 ~~^~~~~~~~~~~~~~~~~~~~~
construction.cpp:85:17: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   85 |  for(int i=0; i < adj[curNode].size(); i++) if(adj[curNode][i] != prev) {
      |               ~~^~~~~~~~~~~~~~~~~~~~~
construction.cpp: In function 'int main()':
construction.cpp:170:8: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  170 |   scanf("%d", &c[i]);
      |   ~~~~~^~~~~~~~~~~~~
construction.cpp:182:8: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  182 |   scanf("%d%d", &U[i], &V[i]);
      |   ~~~~~^~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...