답안 #232812

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
232812 2020-05-18T09:11:51 Z Vimmer Transport (COCI19_transport) C++14
0 / 130
1000 ms 14056 KB
#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;
}
# 결과 실행 시간 메모리 Grader output
1 Incorrect 82 ms 3712 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 103 ms 4032 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Execution timed out 1084 ms 9184 KB Time limit exceeded
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Execution timed out 1081 ms 11512 KB Time limit exceeded
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Execution timed out 1095 ms 14056 KB Time limit exceeded
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 716 ms 5720 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Execution timed out 1066 ms 8056 KB Time limit exceeded
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Execution timed out 1093 ms 9336 KB Time limit exceeded
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Execution timed out 1095 ms 10744 KB Time limit exceeded
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Execution timed out 1091 ms 11512 KB Time limit exceeded
2 Halted 0 ms 0 KB -