Codeforces 846E Chemistry in Berland(防爆long long)

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 种物品,编号从1开始, 1 个编号为i的物品可以转化为 1 个编号为ai的物品, ki 个编号为 ai 的物品可以转化为 1 个编号为i的物品,给你每个物品的需求量和供应量,问能不能通过转化满足要求。

解题思路:

  写法就是一个普通的树形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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值