#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
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);
~~~~~^~~~~~~~~~~~~~~~~~~~~~
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
19 ms |
3320 KB |
Output is correct |
2 |
Correct |
17 ms |
3448 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
18 ms |
3704 KB |
Output is correct |
2 |
Correct |
22 ms |
3960 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
199 ms |
12816 KB |
Output is correct |
2 |
Correct |
180 ms |
11756 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
286 ms |
16256 KB |
Output is correct |
2 |
Correct |
325 ms |
18288 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
402 ms |
21352 KB |
Output is correct |
2 |
Correct |
505 ms |
25336 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
134 ms |
7280 KB |
Output is correct |
2 |
Correct |
70 ms |
6904 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
122 ms |
10348 KB |
Output is correct |
2 |
Correct |
214 ms |
9892 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
317 ms |
12760 KB |
Output is correct |
2 |
Correct |
267 ms |
13548 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
427 ms |
16180 KB |
Output is correct |
2 |
Correct |
377 ms |
16868 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
602 ms |
19996 KB |
Output is correct |
2 |
Correct |
507 ms |
18536 KB |
Output is correct |