E. Chemistry in Berland
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
Igor is a post-graduate student of chemistry faculty in Berland State University (BerSU). He needs to conduct a complicated experiment to write his thesis, but laboratory of BerSU doesn’t contain all the materials required for this experiment.
Fortunately, chemical laws allow material transformations (yes, chemistry in Berland differs from ours). But the rules of transformation are a bit strange.
Berland chemists are aware of n materials, numbered in the order they were discovered. Each material can be transformed into some other material (or vice versa). Formally, for each i (2 ≤ i ≤ n) there exist two numbers xi and ki that denote a possible transformation: ki kilograms of material xi can be transformed into 1 kilogram of material i, and 1 kilogram of material i can be transformed into 1 kilogram of material xi. Chemical processing equipment in BerSU allows only such transformation that the amount of resulting material is always an integer number of kilograms.
For each i (1 ≤ i ≤ n) Igor knows that the experiment requires ai kilograms of material i, and the laboratory contains bi kilograms of this material. Is it possible to conduct an experiment after transforming some materials (or none)?
Input
The first line contains one integer number n (1 ≤ n ≤ 105) — the number of materials discovered by Berland chemists.
The second line contains n integer numbers b1, b2… bn (1 ≤ bi ≤ 1012) — supplies of BerSU laboratory.
The third line contains n integer numbers a1, a2… an (1 ≤ ai ≤ 1012) — the amounts required for the experiment.
Then n - 1 lines follow. j-th of them contains two numbers xj + 1 and kj + 1 that denote transformation of (j + 1)-th material (1 ≤ xj + 1 ≤ j, 1 ≤ kj + 1 ≤ 109).
Output
Print YES if it is possible to conduct an experiment. Otherwise print NO.
Examples
input
3
1 2 3
3 2 1
1 1
1 1
output
YES
input
3
3 2 1
1 2 3
1 1
1 2
output
NO
题目大意:
有
N
种物品,编号从
解题思路:
写法就是一个普通的树形DP(具体写法见代码),不过因为
ai
可以达到
1012
,
ki
可以达到
109
,所以向上转移时减法会爆long long。这时就需要手动防爆,由于向上转移时加法的系数为1,最多只会加
1017
,如果当前要减去的
dp[v]×k[v]
大于INF,即
dp[v]>INF/k[v]
,那么dp[u]一定不会通过加法变成正值,所以我们就可以直接令
dp[u]=−INF
。同理即使dp[v]不大,但在转移后dp[u]小于-INF了,也要把dp[u]置为-INF。
总体思路就是:如果当前操作会导致结果超过INF,并且造成的影响非常大,以至于后边无论怎么操作都不会改变结果,我们就可以直接令它为INF,来起到防止爆long long的目的。
AC代码:
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#include <stack>
using namespace std;
#define INF 0x3f3f3f3f3f3f3f3f
#define LL long long
#define fi first
#define se second
#define sqr(x) ((x)*(x))
const int MAXV=100000+3;
LL V, a[MAXV], b[MAXV];
vector<pair<LL, LL> > G[MAXV];
LL dp[MAXV];
void dfs(LL u)
{
dp[u]=b[u]-a[u];
for(int i=0;i<G[u].size();++i)
{
LL v=G[u][i].fi, rate=G[u][i].se;
dfs(v);
if(dp[v]<0)
{
if(-dp[v]<INF/rate)//不会超过INF,正常处理
dp[u]+=dp[v]*rate;
else dp[u]=-INF;//会导致超过INF,直接置为INF
if(dp[u]<-INF)//超过INF,直接置为INF
dp[u]=-INF;
}
else dp[u]+=dp[v];
}
}
int main()
{
scanf("%lld", &V);
for(int i=1;i<=V;++i)
scanf("%lld", &b[i]);
for(int i=1;i<=V;++i)
scanf("%lld", &a[i]);
for(int v=2;v<=V;++v)
{
LL u, x;
scanf("%lld%lld", &u, &x);
G[u].push_back(make_pair(v, x));
}
dfs(1);
puts(dp[1]>=0?"YES":"NO");
return 0;
}