Submission #97514

#TimeUsernameProblemLanguageResultExecution timeMemory
97514bogdan10bosConstruction of Highway (JOI18_construction)C++14
100 / 100
731 ms27024 KiB
#include <bits/stdc++.h> using namespace std; //#define FILE_IO typedef pair<int, int> pii; typedef long long LL; const int NMAX = 1e5 + 5; int N, K; int v[NMAX], sz[NMAX], chn[NMAX], f[NMAX], pos[NMAX]; vector<int> nodes[NMAX], edg[NMAX]; vector<pii> edges, blk, aux, blocks[NMAX]; class Normalizer { public: map<int, int> mp; vector<int> ord; void add(int x) { if(mp.count(x)) return; mp[x]; ord.push_back(x); } int get(int x) { return mp[x]; } void normalize() { sort(begin(ord), end(ord)); for(int i = 0; i < ord.size(); i++) mp[ ord[i] ] = i + 1; } }nrm; class BinaryIndexedTree { public: vector<int> aib; void init(int N) { aib.resize(N + 5); } void U(int pos, int val) { for(; pos < aib.size(); pos += (pos & (-pos))) aib[pos] += val; } int Q(int pos) { int ans = 0; for(; pos > 0; pos -= (pos & (-pos))) ans += aib[pos]; return ans; } }aib; void DFS(int nod, int fth = 0) { sz[nod] = 1; f[nod] = fth; for(auto &nxt: edg[nod]) { DFS(nxt, nod); sz[nod] += sz[nxt]; if(sz[nxt] > sz[ edg[nod][0] ]) swap(nxt, edg[nod][0]); } if(edg[nod].empty()) chn[nod] = ++K; else chn[nod] = chn[ edg[nod][0] ]; nodes[ chn[nod] ].push_back(nod); pos[nod] = int(nodes[ chn[nod] ].size()) - 1; } int main() { #ifdef FILE_IO freopen("1.in", "r", stdin); //freopen("1.out", "w", stdout); #endif scanf("%d", &N); for(int i = 1; i <= N; i++) scanf("%d", &v[i]), nrm.add(v[i]); nrm.normalize(); for(int i = 1; i <= N; i++) v[i] = nrm.get(v[i]); for(int i = 1; i < N; i++) { int x, y; scanf("%d%d", &x, &y); edg[x].push_back(y); edges.push_back({x, y}); } DFS(1); aib.init(N); blocks[ chn[1] ].push_back({v[1], 1}); for(auto &e: edges) { int x = e.first, y = e.second; int p = pos[x], c = chn[x]; blk.clear(); while(1) { int rem = int(nodes[c].size()) - p; aux.clear(); while(rem) { if(blocks[c].back().second > rem) { aux.push_back({blocks[c].back().first, rem}); blocks[c][ int(blocks[c].size()) - 1 ].second -= rem; break; } rem -= blocks[c].back().second; aux.push_back(blocks[c].back()); blocks[c].pop_back(); } reverse(aux.begin(), aux.end()); for(auto &x: aux) blk.push_back(x); int cnt = int(nodes[c].size() - p); if(chn[y] == c) cnt++; blocks[c].push_back({v[y], cnt}); if(c == chn[1]) break; int nod = f[ nodes[c].back() ]; c = chn[nod], p = pos[nod]; } if(chn[x] != chn[y]) blocks[ chn[y] ].push_back({v[y], 1}); LL ans = 0LL; for(auto &b: blk) { ans += 1LL * b.second * aib.Q(b.first - 1); aib.U(b.first, b.second); } printf("%lld\n", ans); for(auto &b: blk) aib.U(b.first, -b.second); } return 0; }

Compilation message (stderr)

construction.cpp: In member function 'void Normalizer::normalize()':
construction.cpp:34:26: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
         for(int i = 0; i < ord.size(); i++)
                        ~~^~~~~~~~~~~~
construction.cpp: In member function 'void BinaryIndexedTree::U(int, int)':
construction.cpp:51:19: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
         for(; pos < aib.size(); pos += (pos & (-pos)))
               ~~~~^~~~~~~~~~~~
construction.cpp: In function 'int main()':
construction.cpp:91:10: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
     scanf("%d", &N);
     ~~~~~^~~~~~~~~~
construction.cpp:92:51: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
     for(int i = 1; i <= N; i++) scanf("%d", &v[i]), nrm.add(v[i]);
                                 ~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~
construction.cpp:98:14: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
         scanf("%d%d", &x, &y);
         ~~~~~^~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...