제출 #996585

#제출 시각아이디문제언어결과실행 시간메모리
996585TrustfulcomicDynamic Diameter (CEOI19_diameter)C++14
31 / 100
5067 ms321456 KiB
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int,int> ii; vector<ll> vahy; multiset<ll> maxima_centroids; struct Intervalac{ vector<ll> lenost; vector<ll> maxima; }; struct Centroid{ int node; map<int,int> next_centroid; map<int,ii> edge_interval; int listy; Intervalac intervalac; multiset<ll> maxima; map<int,ii> podstromy; }; vector<Centroid> centroids; int int_pow(int x, int e){ if (e == 0) return 1; int m = int_pow(x, e/2); if (e%2 == 0) return m*m; else return m*m*x; } int dfs(vector<bool>& is_centroid, vector<vector<ii>>& strom, map<int,int>& pocty, int parent, int current){ int res = 1; for (auto [_, i] : strom[current]){ if (i == parent || is_centroid[i]) continue; res += dfs(is_centroid, strom, pocty, current, i); } pocty[current] = res; return res; } ii dfs2(vector<bool>& is_centroid, vector<vector<ii>>& strom, map<int, ii>& edge_interval, int& found, int parent, int current, vector<int>& indexy_hran, map<int,ii>& podstromy){ ii res = {INT_MAX, INT_MIN}; for (auto [i, j] : strom[current]){ indexy_hran.push_back(i); if (j == parent || is_centroid[j]) continue; ii returned = dfs2(is_centroid, strom, edge_interval, found, current, j, indexy_hran, podstromy); edge_interval[i] = returned; if (parent == -1){ for (int k : indexy_hran){ podstromy[k] = returned; } indexy_hran.clear(); } res.first = min(res.first, returned.first); res.second = max(res.second, returned.second); } if (res.first == INT_MAX){ res = {found, found}; found++; } return res; } Intervalac create_intervalac(int n){ Intervalac res; while(n & (n - 1)) n++; res.maxima = vector<ll>(2*n, 0); res.lenost = vector<ll>(2*n, 0); return res; } vector<int> find_centroids(vector<bool>& is_centroid, vector<vector<ii>>& strom, int start){ maxima_centroids.insert(0); map<int, int> pocty; dfs(is_centroid, strom, pocty, -1, start); int current = start; while (true){ int go_to = -1; for (auto [_, i] : strom[current]){ if (is_centroid[i]) continue; if (pocty[i] > pocty[current]/2){ go_to = i; break; } } if (go_to == -1) break; pocty[current] -= pocty[go_to]; pocty[go_to] += pocty[current]; current = go_to; } if (pocty[current] == 1) return {}; Centroid centr; centr.node = current; is_centroid[current] = true; int found = 0; vector<int> indexy_hran; dfs2(is_centroid, strom, centr.edge_interval, found, -1, centr.node, indexy_hran, centr.podstromy); centr.listy = found; for (int i = 0; i<strom[centr.node].size(); i++){ centr.maxima.insert(0); } centr.intervalac = create_intervalac(centr.listy); vector<int> sousedi; for (auto [i, j] : strom[current]){ if (is_centroid[j]) continue; sousedi.push_back(i); vector<int> sousedi_sousedu = find_centroids(is_centroid, strom, j); for (int k : sousedi_sousedu) { sousedi.push_back(k); centr.next_centroid[k] = centroids.size()-1; } } centroids.push_back(centr); return sousedi; } ll get_max(Intervalac& inter, int i, int l, int r, int a, int b){ inter.maxima[i] += inter.lenost[i]; if (2*i< inter.lenost.size()){ inter.lenost[2*i] += inter.lenost[i]; inter.lenost[2*i+1] += inter.lenost[i]; } inter.lenost[i] = 0; if (l == a && r == b){ return inter.maxima[i]; } else if (r <= (a+b)/2){ return get_max(inter, 2*i, l, r, a, (a+b)/2); } else if (l >= (a+b)/2){ return get_max(inter, 2*i+1, l, r, (a+b)/2, b); } else { return max(get_max(inter, 2*i, l, (a+b)/2, a, (a+b)/2),get_max(inter, 2*i+1, (a+b)/2, r, (a+b)/2, b)); } } void vyres_lesnost(Intervalac& inter, int i){ inter.maxima[i] += inter.lenost[i]; if (2*i< inter.lenost.size()){ inter.lenost[2*i] += inter.lenost[i]; inter.lenost[2*i+1] += inter.lenost[i]; } inter.lenost[i] = 0; } void set_val(Intervalac& inter, int i, int l, int r, int a, int b, ll add){ vyres_lesnost(inter, i); if (l == a && r == b){ inter.lenost[i] = add; } else if (r <= (a+b)/2){ set_val(inter, 2*i, l, r, a, (a+b)/2, add); } else if (l >= (a+b)/2){ set_val(inter, 2*i+1, l, r, (a+b)/2, b, add); } else { set_val(inter, 2*i, l, (a+b)/2, a, (a+b)/2, add); set_val(inter, 2*i+1, (a+b)/2, r, (a+b)/2, b, add); } if (2*i < inter.lenost.size()){ vyres_lesnost(inter, 2*i); vyres_lesnost(inter, 2*i+1); inter.maxima[i] = max(inter.maxima[2*i], inter.maxima[2*i+1]); } } void update(Centroid& centr, ll hrana, ll set_to){ ll maximum_centroidu = 0; auto it = centr.maxima.end(); it--; maximum_centroidu += *it; if (it != centr.maxima.begin()){ it--; maximum_centroidu += *it; } maxima_centroids.erase(maxima_centroids.find(maximum_centroidu)); centr.maxima.erase(centr.maxima.find(get_max(centr.intervalac, 1, centr.podstromy[hrana].first, centr.podstromy[hrana].second+1, 0, centr.intervalac.maxima.size()/2))); set_val(centr.intervalac, 1, centr.edge_interval[hrana].first, centr.edge_interval[hrana].second+1, 0, centr.intervalac.maxima.size()/2, set_to-vahy[hrana]); centr.maxima.insert(get_max(centr.intervalac, 1, centr.podstromy[hrana].first, centr.podstromy[hrana].second+1, 0, centr.intervalac.maxima.size()/2)); maximum_centroidu = 0; it = centr.maxima.end(); it--; maximum_centroidu += *it; if (it != centr.maxima.begin()){ it--; maximum_centroidu += *it; } maxima_centroids.insert(maximum_centroidu); if (centr.next_centroid.find(hrana) != centr.next_centroid.end()) update(centroids[centr.next_centroid[hrana]], hrana, set_to); } int main(){ int n,q; cin >> n >> q; ll w; cin >> w; vahy.resize(n-1); vector<vector<ii>> strom(n); for (int i = 0; i<n-1; i++){ int a,b; cin >> a >> b; ll c; cin >> c; vahy[i] = c; strom[a-1].push_back({i, b-1}); strom[b-1].push_back({i, a-1}); } vector<bool> is_centroid(n, false); find_centroids(is_centroid, strom, 0); for (int i = 0; i<n-1; i++){ update(centroids.back(), i, 2*vahy[i]); } ll last = 0; for (int i = 0 ; i<q; i++){ ll d; cin >> d; ll e; cin >> e; update(centroids.back(), (d+last)%(n-1), (e+last)%w); vahy[(d+last)%(n-1)] = (e+last)%w; last = *maxima_centroids.rbegin(); cout << last << endl; } }

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

diameter.cpp: In function 'int dfs(std::vector<bool>&, std::vector<std::vector<std::pair<int, int> > >&, std::map<int, int>&, int, int)':
diameter.cpp:36:15: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17'
   36 |     for (auto [_, i] : strom[current]){
      |               ^
diameter.cpp: In function 'ii dfs2(std::vector<bool>&, std::vector<std::vector<std::pair<int, int> > >&, std::map<int, std::pair<int, int> >&, int&, int, int, std::vector<int>&, std::map<int, std::pair<int, int> >&)':
diameter.cpp:47:15: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17'
   47 |     for (auto [i, j] : strom[current]){
      |               ^
diameter.cpp: In function 'std::vector<int> find_centroids(std::vector<bool>&, std::vector<std::vector<std::pair<int, int> > >&, int)':
diameter.cpp:90:19: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17'
   90 |         for (auto [_, i] : strom[current]){
      |                   ^
diameter.cpp:115:22: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::pair<int, int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  115 |     for (int i = 0; i<strom[centr.node].size(); i++){
      |                     ~^~~~~~~~~~~~~~~~~~~~~~~~~
diameter.cpp:122:15: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17'
  122 |     for (auto [i, j] : strom[current]){
      |               ^
diameter.cpp: In function 'll get_max(Intervalac&, int, int, int, int, int)':
diameter.cpp:138:12: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  138 |     if (2*i< inter.lenost.size()){
      |         ~~~^~~~~~~~~~~~~~~~~~~~~
diameter.cpp: In function 'void vyres_lesnost(Intervalac&, int)':
diameter.cpp:157:12: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  157 |     if (2*i< inter.lenost.size()){
      |         ~~~^~~~~~~~~~~~~~~~~~~~~
diameter.cpp: In function 'void set_val(Intervalac&, int, int, int, int, int, ll)':
diameter.cpp:178:13: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  178 |     if (2*i < inter.lenost.size()){
      |         ~~~~^~~~~~~~~~~~~~~~~~~~~
#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...