結果

問題 No.899 γatheree
ユーザー fumiphysfumiphys
提出日時 2019-10-04 22:50:10
言語 C++14
(gcc 12.3.0 + boost 1.83.0)
結果
AC  
実行時間 649 ms / 2,000 ms
コード長 7,220 bytes
コンパイル時間 1,865 ms
コンパイル使用メモリ 191,160 KB
実行使用メモリ 195,964 KB
最終ジャッジ日時 2024-10-03 08:19:23
合計ジャッジ時間 13,862 ms
ジャッジサーバーID
(参考情報)
judge5 / judge2
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 3 ms
8,192 KB
testcase_01 AC 3 ms
8,320 KB
testcase_02 AC 3 ms
8,320 KB
testcase_03 AC 3 ms
8,320 KB
testcase_04 AC 3 ms
8,320 KB
testcase_05 AC 4 ms
8,448 KB
testcase_06 AC 623 ms
183,476 KB
testcase_07 AC 616 ms
179,408 KB
testcase_08 AC 625 ms
191,684 KB
testcase_09 AC 561 ms
138,320 KB
testcase_10 AC 611 ms
183,552 KB
testcase_11 AC 581 ms
167,124 KB
testcase_12 AC 576 ms
162,944 KB
testcase_13 AC 594 ms
167,040 KB
testcase_14 AC 635 ms
195,964 KB
testcase_15 AC 561 ms
146,676 KB
testcase_16 AC 571 ms
154,752 KB
testcase_17 AC 578 ms
154,880 KB
testcase_18 AC 649 ms
191,704 KB
testcase_19 AC 587 ms
171,136 KB
testcase_20 AC 602 ms
171,008 KB
testcase_21 AC 477 ms
40,704 KB
testcase_22 AC 486 ms
40,828 KB
testcase_23 AC 470 ms
40,576 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

// includes
#include <bits/stdc++.h>
using namespace std;

// macros
#define pb emplace_back
#define mk make_pair
#define FOR(i, a, b) for(int i=(a);i<(b);++i)
#define rep(i, n) FOR(i, 0, n)
#define rrep(i, n) for(int i=((int)(n)-1);i>=0;i--)
#define irep(itr, st) for(auto itr = (st).begin(); itr != (st).end(); ++itr)
#define irrep(itr, st) for(auto itr = (st).rbegin(); itr != (st).rend(); ++itr)
#define all(x) (x).begin(),(x).end()
#define sz(x) ((int)(x).size())
#define UNIQUE(v) v.erase(unique(v.begin(), v.end()), v.end())
#define bit(n) (1LL<<(n))
// functions
template <class T>bool chmax(T &a, const T &b){if(a < b){a = b; return 1;} return 0;}
template <class T>bool chmin(T &a, const T &b){if(a > b){a = b; return 1;} return 0;}
template <typename T> istream &operator>>(istream &is, vector<T> &vec){for(auto &v: vec)is >> v; return is;}
template <typename T> ostream &operator<<(ostream &os, const vector<T>& vec){for(int i = 0; i < vec.size(); i++){ os << vec[i]; if(i + 1 != vec.size())os << " ";} return os;}
template <typename T> ostream &operator<<(ostream &os, const set<T>& st){for(auto itr = st.begin(); itr != st.end(); ++itr){ os << *itr; auto titr = itr; if(++titr != st.end())os << " ";} return os;}
template <typename T> ostream &operator<<(ostream &os, const unordered_set<T>& st){for(auto itr = st.begin(); itr != st.end(); ++itr){ os << *itr; auto titr = itr; if(++titr != st.end())os << " ";} return os;}
template <typename T> ostream &operator<<(ostream &os, const multiset<T>& st){for(auto itr = st.begin(); itr != st.end(); ++itr){ os << *itr; auto titr = itr; if(++titr != st.end())os << " ";} return os;}
template <typename T> ostream &operator<<(ostream &os, const unordered_multiset<T>& st){for(auto itr = st.begin(); itr != st.end(); ++itr){ os << *itr; auto titr = itr; if(++titr != st.end())os << " ";} return os;}
template <typename T1, typename T2> ostream &operator<<(ostream &os, const pair<T1, T2> &p){os << p.first << " " << p.second; return os;}
template <typename T1, typename T2> ostream &operator<<(ostream &os, const map<T1, T2> &mp){for(auto itr = mp.begin(); itr != mp.end(); ++itr){ os << itr->first << ":" << itr->second; auto titr = itr; if(++titr != mp.end())os << " "; } return os;}
template <typename T1, typename T2> ostream &operator<<(ostream &os, const unordered_map<T1, T2> &mp){for(auto itr = mp.begin(); itr != mp.end(); ++itr){ os << itr->first << ":" << itr->second; auto titr = itr; if(++titr != mp.end())os << " "; } return os;}
//  types
using ll = long long int;
using P = pair<int, int>;
// constants
const int inf = 1e9;
const ll linf = 1LL << 50;
const double EPS = 1e-10;
const int mod = 1000000007;
const int dx[4] = {-1, 0, 1, 0};
const int dy[4] = {0, -1, 0, 1};
// io
struct fast_io{
  fast_io(){ios_base::sync_with_stdio(false); cin.tie(0); cout << fixed << setprecision(20);}
} fast_io_;

template<typename T, typename E>
struct LazySegmentTree_ {
  function<T(T, T)> f; // aggregation
  function<E(E, E)> h; // update lazy element
  function<T(T, E, int)> p; // update element with lazy element
  int n;
  T def;
  E l_def;
  vector<T> vec;
  vector<E> lazy;
  LazySegmentTree_(){}
  LazySegmentTree_(int n_, function<T(T, T)> f, T def,
                   function<E(E, E)> h, E l_def, function<T(T, E, int)> p,
                   vector<T> v=vector<T>()): f(f), def(def), h(h), l_def(l_def), p(p){

    // initialize vector
    n = 1;
    while(n < n_){
      n *= 2;
    }
    vec = vector<T>(2*n-1, def);
    lazy = vector<E>(2*n-1, l_def);

    // initialize segment tree
    for(int i = 0; i < v.size(); i++){
      vec[i + n - 1] = v[i];
    }
    for(int i = n - 2; i >= 0; i--){
      vec[i] = f(vec[2*i+1], vec[2*i+2]);
    }
  }
  void eval(int k, int len){
    if(lazy[k] != l_def){
      if(k < n - 1){
        lazy[2*k+1] = h(lazy[2*k+1], lazy[k]);
        lazy[2*k+2] = h(lazy[2*k+2], lazy[k]);
      }
      vec[k] = p(vec[k], lazy[k], len);
      lazy[k] = l_def;
    }
  }
  E update(int a, int b, const E &val, int k, int l, int r){
    eval(k, r - l);
    if(r <= a || b <= l){
      return vec[k];
    }else if(a <= l && r <= b){
      lazy[k] = h(lazy[k], val);
      eval(k, r - l);
      return vec[k];
    }else{
      return vec[k] = f(update(a, b, val, 2*k+1, l, (l+r)/2),
                        update(a, b, val, 2*k+2, (l+r)/2, r));
    }
  }
  E update(int a, int b, E val){
    return update(a, b, val, 0, 0, n);
  }
  // [l, r) -> [a, b) (at k)
  T query(int a, int b, int k, int l, int r){
    eval(k, r - l);
    if(r <= a || b <= l)return def;
    if(a <= l && r <= b)return vec[k];
    T ld = query(a, b, 2*k+1, l, (l+r)/2);
    T rd = query(a, b, 2*k+2, (l+r)/2, r);
    return f(ld, rd);
  }
  T query(int a, int b){
    return query(a, b, 0, 0, n);
  }
};

template<typename T, typename E>
using LazySegmentTree = struct LazySegmentTree_<T, E>;
using LazySegmentTreeI = LazySegmentTree<int, int>;
using LazySegmentTreeL = LazySegmentTree<long long, long long>;


vector<int> edge[100010], child[100010];
bool vis[100010];
int h[100010], l[100010], r[100010], idx[100010], par[100010];
int l2[100010], r2[100010];

vector<vector<int>> hv;
int H = 0;

int dfs(int i){
  H = max(H, h[i]);
  vis[i] = true;
  hv[h[i]].pb(i);
  l[i] = inf, r[i] = -1;
  l2[i] = inf, r2[i] = -1;
  for(auto e: edge[i]){
    if(vis[e])continue;
    child[i].pb(e);
    h[e] = h[i] + 1;
    par[e] = i;
    int u = dfs(e);
    l[i] = min(l[i], u);
    r[i] = max(r[i], u);
    l2[i] = min(l2[i], l[e]);
    r2[i] = max(r2[i], r[e]);
  }
  return idx[i] = sz(hv[h[i]]) - 1;
}

int main(int argc, char const* argv[])
{
  int n; cin >> n;
  rep(i, n - 1){
    int u, v; cin >> u >> v;
    edge[u].pb(v);
    edge[v].pb(u);
  }
  hv.resize(n);
  dfs(0);
  vector<ll> a(n); cin >> a;

  H++;
  vector<LazySegmentTreeL> seg(H);
  rep(i, H){
    vector<ll> v(sz(hv[i]));
    rep(j, sz(hv[i]))v[j] = a[hv[i][j]];
    seg[i] = LazySegmentTreeL(n, [](ll a, ll b){return a + b;},
                           0, [](ll a, ll b){return b;},
                           -linf, [](ll a, ll b, int c){return b * c;},
                           v);
  }

  int q; cin >> q;
  rep(i, q){
    int x; cin >> x;
    ll res = 0;
    if(sz(child[x]) > 0){
      ll sum = seg[h[x]+1].query(l[x], r[x] + 1);
      seg[h[x]+1].update(l[x], r[x] + 1, 0);
      res += sum;
      if(l2[x] != inf){
        sum = seg[h[x]+2].query(l2[x], r2[x] + 1);
        res += sum;
        seg[h[x]+2].update(l2[x], r2[x] + 1, 0);
      }
    }
    if(h[x] > 0){
      ll sum = seg[h[x]-1].query(idx[par[x]], idx[par[x]] + 1);
      seg[h[x]-1].update(idx[par[x]], idx[par[x]] + 1, 0);
      res += sum;
      if(sz(child[par[x]]) > 0){
        sum = seg[h[x]].query(l[par[x]], r[par[x]] + 1);
        res += sum;
        seg[h[x]].update(l[par[x]], r[par[x]] + 1, 0);
      }
    }
    if(h[x] == 0){
      ll sum = seg[0].query(0, 1);
      res += sum;
      seg[0].update(0, 1, 0);
    }
    if(h[x] > 1){
      ll sum = seg[h[x]-2].query(idx[par[par[x]]], idx[par[par[x]]] + 1);
      seg[h[x]-2].update(idx[par[par[x]]], idx[par[par[x]]] + 1, 0);
      res += sum;
    }
    seg[h[x]].update(idx[x], idx[x] + 1, res);
    cout << res << endl;
  }
  return 0;
}
0