Submission #96662

#TimeUsernameProblemLanguageResultExecution timeMemory
96662noneTPTransport (COCI19_transport)C++14
130 / 130
602 ms25336 KiB
#include <cstdio> #include <vector> #include <algorithm> using namespace std; typedef tuple<int, int, int> tp; typedef long long LL; typedef long double LD; typedef pair<int, int> pii; typedef pair<int, LL> pil; typedef pair<LL, int> pli; typedef pair<LL, LL> pll; typedef pair<pii, int> piipi; typedef pair<int, pii> pipii; typedef pair<pii, pii> piipii; typedef pair<LL, pii> plpii; typedef pair<LD, LD> pdd; typedef pair<LD, int> pdi; typedef pair<LD, LL> pdl; typedef pair<int, LD> pid; typedef pair<LL, LD> pld; const int mod = 1e9 + 7; const int hf = 999983; const int N = 100000; LL ans = 0; int A[N+5]; vector<pii> g[N+5]; int par[18][N+5]; int depth[N+5]; bool vis[N+5]; int n = N; int nn = 0; int sub[N+5]; int par2[N+5]; void init(int m){ n = m; for(int i=1;i<=n;i++){ g[i].clear(); depth[i] = 0; vis[i] = 0; sub[i] = 0; par2[i] = 0; for(int j=0;j<18;j++) par[j][i] = 0; } } void addEdge(int a, int b, int c){ g[a].push_back(pii(b, c)); g[b].push_back(pii(a, c)); } void dfs(int u, int p, int d){ depth[u] = d; par[0][u] = p; for(int i=0;i<g[u].size();i++){ int v = g[u][i].first; if(v == p) continue; dfs(v, u, d+1); } } int LCA(int a, int b){ if(depth[b] > depth[a]) swap(a, b); int diff = depth[a] - depth[b]; for(int i=17;i>=0;i--) if((diff>>i)&1) a = par[i][a]; if(a == b) return a; for(int i=17;i>=0;i--) if(par[i][a] != par[i][b]) a = par[i][a], b = par[i][b]; return par[0][a]; } int dist(int a, int b){ return depth[a] + depth[b] - 2*depth[LCA(a, b)]; } void cal_sz(int u, int p){ sub[u] = 1; nn++; for(int i=0;i<g[u].size();i++){ int v = g[u][i].first; if(v == p || vis[v]) continue; cal_sz(v, u); sub[u] += sub[v]; } } int find_centroid(int u, int p){ for(int i=0;i<g[u].size();i++){ int v = g[u][i].first; if(v == p || vis[v]) continue; if(sub[v] > nn/2) return find_centroid(v, u); } return u; } int ft[N+5]; void update(int i, int v){ for(;i<=N;i+=(i&-i)) ft[i]+=v; } int query(int i){ int result = 0; for(;i>0;i-=(i&-i)) result+=ft[i]; return result; } vector<pli> check1, add; void dfs2(int u, int p, LL full, LL mn){ check1.push_back(pli(mn, u)); if(mn >= 0) ans++; for(int i=0;i<g[u].size();i++){ int v = g[u][i].first, w = g[u][i].second; if(v == p || vis[v]) continue; dfs2(v, u, full+A[u]-w, min(mn, full+A[u]-w)); } } vector<int> check2; LL dp[N+5]; void dfs3(int u, int p, LL val, LL go, LL full, LL mn){ dp[u] = go; add.push_back(pli(mn, u)); if(val >= 0) check2.push_back(u); for(int i=0;i<g[u].size();i++){ int v = g[u][i].first, w = g[u][i].second; if(v == p || vis[v]) continue; dfs3(v, u, min(val+A[v]-w, (LL)A[v]-w), go+A[v]-w, full+A[u]-w, min(mn, full+A[u]-w)); } } void decompose(int u, int p){ nn = 0; cal_sz(u, 0); int centroid = find_centroid(u, 0); vis[centroid] = 1; par2[centroid] = p; check1.clear(), check2.clear(); check1.push_back(pli(-1e18, 0)); LL full = A[centroid]; for(int i=0;i<g[centroid].size();i++){ int v = g[centroid][i].first, w = g[centroid][i].second; if(v == p || vis[v]) continue; dfs2(v, centroid, full-w, full-w); } sort(check1.begin(), check1.end()); for(int i=1;i<check1.size();i++) update(i, 1); for(int i=0;i<g[centroid].size();i++){ int v = g[centroid][i].first, w = g[centroid][i].second; if(v == p || vis[v]) continue; check2.clear(), add.clear(); dfs3(v, centroid, A[v]-w, A[v]-w, full-w, full-w); ans += check2.size(); for(int j=0;j<add.size();j++){ int k = lower_bound(check1.begin(), check1.end(), add[j]) - check1.begin(); update(k, -1); } for(int j=0;j<check2.size();j++){ int k = check2[j]; int l = lower_bound(check1.begin(), check1.end(), pli(-dp[k], 0)) - check1.begin(); ans += query(N) - query(l-1); } for(int j=0;j<add.size();j++){ int k = lower_bound(check1.begin(), check1.end(), add[j]) - check1.begin(); update(k, 1); } } for(int i=1;i<check1.size();i++) update(i, -1); for(int i=0;i<g[centroid].size();i++){ int v = g[centroid][i].first; if(v == p || vis[v]) continue; decompose(v, centroid); } } void getParent(){ for(int j=1;j<17;j++){ for(int i=1;i<=n;i++){ if(par[j-1][i] != 0) par[j][i] = par[j-1][par[j-1][i]]; } } } int main(){ int n; scanf("%d", &n); for(int i=1;i<=n;i++) scanf("%d", &A[i]); init(n); for(int i=2;i<=n;i++){ int a, b, c; scanf("%d%d%d", &a, &b, &c); addEdge(a, b, c); } dfs(1, 0, 0); getParent(); decompose(1, 0); printf("%lld\n", ans); }

Compilation message (stderr)

transport.cpp: In function 'void dfs(int, int, int)':
transport.cpp:58:18: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     for(int i=0;i<g[u].size();i++){
                 ~^~~~~~~~~~~~
transport.cpp: In function 'void cal_sz(int, int)':
transport.cpp:81:18: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     for(int i=0;i<g[u].size();i++){
                 ~^~~~~~~~~~~~
transport.cpp: In function 'int find_centroid(int, int)':
transport.cpp:90:18: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     for(int i=0;i<g[u].size();i++){
                 ~^~~~~~~~~~~~
transport.cpp: In function 'void dfs2(int, int, LL, LL)':
transport.cpp:112:18: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     for(int i=0;i<g[u].size();i++){
                 ~^~~~~~~~~~~~
transport.cpp: In function 'void dfs3(int, int, LL, LL, LL, LL)':
transport.cpp:125:18: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     for(int i=0;i<g[u].size();i++){
                 ~^~~~~~~~~~~~
transport.cpp: In function 'void decompose(int, int)':
transport.cpp:143:18: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     for(int i=0;i<g[centroid].size();i++){
                 ~^~~~~~~~~~~~~~~~~~~
transport.cpp:150:18: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     for(int i=1;i<check1.size();i++) update(i, 1);
                 ~^~~~~~~~~~~~~~
transport.cpp:151:18: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     for(int i=0;i<g[centroid].size();i++){
                 ~^~~~~~~~~~~~~~~~~~~
transport.cpp:157:22: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
         for(int j=0;j<add.size();j++){
                     ~^~~~~~~~~~~
transport.cpp:161:22: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
         for(int j=0;j<check2.size();j++){
                     ~^~~~~~~~~~~~~~
transport.cpp:166:22: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
         for(int j=0;j<add.size();j++){
                     ~^~~~~~~~~~~
transport.cpp:171:18: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     for(int i=1;i<check1.size();i++) update(i, -1);
                 ~^~~~~~~~~~~~~~
transport.cpp:173:18: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     for(int i=0;i<g[centroid].size();i++){
                 ~^~~~~~~~~~~~~~~~~~~
transport.cpp: In function 'int main()':
transport.cpp:191:10: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
     scanf("%d", &n);
     ~~~~~^~~~~~~~~~
transport.cpp:192:32: 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", &A[i]);
                           ~~~~~^~~~~~~~~~~~~
transport.cpp:196:14: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
         scanf("%d%d%d", &a, &b, &c);
         ~~~~~^~~~~~~~~~~~~~~~~~~~~~
#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...