Submission #232812

#TimeUsernameProblemLanguageResultExecution timeMemory
232812VimmerTransport (COCI19_transport)C++14
0 / 130
1095 ms14056 KiB
#include <bits/stdc++.h> //#include <ext/pb_ds/assoc_container.hpp> //#include <ext/pb_ds/tree_policy.hpp> //#pragma GCC optimize("unroll-loops") //#pragma GCC optimize("-O3") //#pragma GCC optimize("Ofast") #define sz(x) ll(x.size()) #define N 100015 #define base 1000000 #define M ll(1e9+7) #define F first #define S second #define pb push_back #define in insert #define eb emplace_back #define ed "\n" using namespace std; //using namespace __gnu_pbds; typedef long long ll; typedef long double ld; typedef short int si; //typedef tree<ll, null_type, less<ll>, rb_tree_tag, tree_order_statistics_node_update> ordered_set; ll ans, t[N]; int a[N], n, siz[N]; vector <pair <int, int> > g[N]; map <ll, int> mp; bool mk[N]; vector <ll> se; void add(int v, int val) {for (; v < N; v = (v | (v + 1))) t[v] += val;} void del(int v, int val) {for (; v < N; v = (v | (v + 1))) t[v] -= val;} ll sum(int v) {ll res = 0; for (; v >= 0; v = (v & (v + 1)) - 1) res += t[v]; return res;} void dfs(int v, int p) { siz[v] = 1; for (auto it : g[v]) { if (it.F == p || mk[it.F]) continue; dfs(it.F, v); siz[v] += siz[it.F]; } } void rec_add(int v, int p, ll cur, ll sm, bool f) { siz[v] = 1; cur += ll(a[v]); if (f) mp[sm]++; else { auto it = upper_bound(se.begin(), se.end(), sm); if (it != se.begin()) { it--; int itr = (it - se.begin()); add(itr, 1); } } for (auto it : g[v]) { if (it.F == p || mk[it.F]) continue; rec_add(it.F, v, cur - ll(it.S), sm + max(0ll, ll(it.S) - cur), f); siz[v] += siz[it.F]; } } void rec_del(int v, int p, ll cur, ll sm) { cur += ll(a[v]); auto it = upper_bound(se.begin(), se.end(), sm); if (it != se.begin()) { it--; int itr = (it - se.begin()); del(itr, 1); } for (auto it : g[v]) { if (it.F == p || mk[it.F]) continue; rec_del(it.F, v, cur - ll(it.S), sm + max(0ll, ll(it.S) - cur)); } } int fnd_cent(int v, int p) { if (p != -1) { swap(siz[v], siz[p]); siz[p] = siz[v] - siz[p]; } bool good = 1; for (auto it : g[v]) { if (mk[it.F]) continue; if (siz[it.F] + siz[it.F] > siz[v]) {good = 0; break;} } if (good) return v; for (auto it : g[v]) { if (it.F == p || mk[it.F]) continue; int root = fnd_cent(it.F, v); if (root != -1) return root; } return -1; } void spusk(int v, int p, ll sm, ll cost, ll need) { need += cost; need = max(0ll, need - a[v]); sm += a[v]; sm -= cost; if (need == 0) { auto it = upper_bound(se.begin(), se.end(), sm); if (it != se.begin()) { it--; int itr = (it - se.begin()); ans += ll(sum(itr)); } ans++; } for (auto it : g[v]) { if (it.F == p || mk[it.F]) continue; spusk(it.F, v, sm, it.S, need); } } void calc(int v) { mk[v] = 1; mp.clear(); se.clear(); memset(t, 0, sizeof(t)); for (auto it : g[v]) { if (mk[it.F]) continue; rec_add(it.F, -1, 0, it.S, 1); } int i = 0; for (auto it : mp) { add(i, it.S); i++; se.pb(it.F); } for (auto it : g[v]) { if (mk[it.F]) continue; rec_del(it.F, -1, 0, it.S); spusk(it.F, -1, a[v], it.S, 0); rec_add(it.F, -1, 0, it.S, 0); } auto it = upper_bound(se.begin(), se.end(), a[v]); if (it != se.begin()) { it--; int itr = (it - se.begin()); ans += ll(sum(itr)); } for (auto it : g[v]) { if (mk[it.F]) continue; int root = fnd_cent(it.F, -1); if (root != -1) calc(root); } } int main() { //freopen("input.txt","r",stdin); freopen("output.txt","w",stdout); ios_base::sync_with_stdio(0); istream::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin >> n; for (int i = 1; i <= n; i++) cin >> a[i]; for (int i = 1; i < n; i++) { int x, y, z; cin >> x >> y >> z; g[x].pb({y, z}); g[y].pb({x, z}); } dfs(1, -1); int root = fnd_cent(1, -1); calc(root); cout << ans << endl; }
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...