Submission #828641

#TimeUsernameProblemLanguageResultExecution timeMemory
828641rainboyArboras (RMI20_arboras)C11
100 / 100
111 ms21464 KiB
#include <stdio.h> #include <stdlib.h> #define N 100000 #define N_ (1 << 17) /* N_ = pow2(ceil(log2(N + 1))) */ #define MD 1000000007 long long max(long long a, long long b) { return a > b ? a : b; } int *ej[N], eo[N], n; void append(int i, int j) { int o = eo[i]++; if (o >= 2 && (o & o - 1) == 0) ej[i] = (int *) realloc(ej[i], o * 2 * sizeof *ej[i]); ej[i][o] = j; } int dd[N], pp[N], qq[N], jj[N], jj1[N], jj2[N], ta[N], tb[N], qu[N], ww[N]; long long dp[N]; int dfs1(int p, int i, int d) { int o, s, k_, j_, j1, j2; dd[i] = d, pp[i] = p; s = 1, k_ = 0, j_ = -1, j1 = -1, j2 = -1; for (o = eo[i]; o--; ) { int j = ej[i][o]; if (j != p) { int k = dfs1(i, j, d + 1); s += k; if (k_ < k) k_ = k, j_ = j; dp[j] += ww[j]; if (j1 == -1 || dp[j1] < dp[j]) j2 = j1, j1 = j; else if (j2 == -1 || dp[j2] < dp[j]) j2 = j; } } jj[i] = j_; dp[i] = j1 == -1 ? 0 : dp[j1], jj1[i] = j1, jj2[i] = j2; return s; } long long st[N_ * 2], lz[N_]; int h_, n_; void put(int i, long long x) { st[i] += x; if (i < n_) lz[i] += x; } void pus(int i) { if (lz[i]) put(i << 1 | 0, lz[i]), put(i << 1 | 1, lz[i]), lz[i] = 0; } void pul(int i) { if (!lz[i]) st[i] = max(st[i << 1 | 0], st[i << 1 | 1]); } void push(int i) { int h; for (h = h_; h > 0; h--) pus(i >> h); } void pull(int i) { while (i > 1) pul(i >>= 1); } void build() { static long long dd[N + 1]; int i; for (i = 1; i < n; i++) dd[ta[i]] += ww[i], dd[tb[i]] -= ww[i]; for (i = 1; i < n; i++) dd[i] += dd[i - 1]; for (i = 0; i < n_; i++) st[n_ + i] = i < n ? dd[i] : 0; for (i = n_ - 1; i > 0; i--) pul(i); } void update(int l, int r, int x) { int l_ = l += n_, r_ = r += n_; push(l_), push(r_); for ( ; l <= r; l >>= 1, r >>= 1) { if ((l & 1) == 1) put(l++, x); if ((r & 1) == 0) put(r--, x); } pull(l_), pull(r_); } long long query(int l, int r) { long long x; push(l += n_), push(r += n_); x = 0; for ( ; l <= r; l >>= 1, r >>= 1) { if ((l & 1) == 1) x = max(x, st[l++]); if ((r & 1) == 0) x = max(x, st[r--]); } return x; } int st_[N_ * 2]; void pul_(int i) { st_[i] = st_[i << 1 | 0] && st_[i << 1 | 1]; } void update_(int i, int x) { st_[i += n_] = x; while (i > 1) pul_(i >>= 1); } int query_(int r) { int l = 0; for (l += n_, r += n_; l <= r; l >>= 1, r >>= 1) if ((r & 1) == 0) { if (!st_[r]) { while (r < n_) r = !st_[r << 1 | 1] ? r << 1 | 1 : r << 1 | 0; return r - n_; } r--; } return -1; } void dfs2(int p, int i, int q) { static int time; int o, j_; qu[ta[i] = time++] = i; qq[i] = q; j_ = jj[i]; if (j_ != -1) { dfs2(i, j_, q); update_(ta[j_], j_ == jj1[i]); } for (o = eo[i]; o--; ) { int j = ej[i][o]; if (j != p && j != j_) dfs2(i, j, j); } tb[i] = time; } int main() { int q, i, j, w, sum; scanf("%d", &n); for (i = 0; i < n; i++) ej[i] = (int *) malloc(2 * sizeof *ej[i]); for (j = 1; j < n; j++) { scanf("%d", &pp[j]); append(pp[j], j); } for (j = 1; j < n; j++) scanf("%d", &ww[j]); dfs1(-1, 0, 0); while (1 << h_ <= n) h_++; n_ = 1 << h_; dfs2(-1, 0, 0); build(); sum = 0; for (i = 0; i < n; i++) sum = (sum + (jj1[i] == -1 ? 0 : dp[jj1[i]]) + (jj2[i] == -1 ? 0 : dp[jj2[i]])) % MD; scanf("%d", &q); printf("%d\n", sum); while (q--) { int x; long long d, d1, d2; scanf("%d%d", &j, &w); update(ta[j], tb[j] - 1, w); ww[j] += w, x = w; while (1) { i = qu[query_(ta[j])]; sum = (sum + (long long) x * (dd[j] - dd[i])) % MD; j = i; if (j == 0) break; i = pp[j]; if (jj1[i] == j) sum = (sum + x) % MD; else { d = query(ta[j], tb[j] - 1); d1 = query(ta[jj1[i]], tb[jj1[i]] - 1); d2 = query(ta[jj2[i]], tb[jj2[i]] - 1); if (d1 < d) { sum = (sum + (j == jj2[i] ? x : d - d2)) % MD; x = d - d1; jj2[i] = jj1[i], jj1[i] = j; update_(ta[jj[i]], jj[i] == j); } else { if (jj2[i] == j) sum = (sum + x) % MD; else if (d2 < d) { sum = (sum + d - d2) % MD; jj2[i] = j; } break; } } j = i; } if (sum < 0) sum += MD; printf("%d\n", sum); } return 0; }

Compilation message (stderr)

arboras.c: In function 'append':
arboras.c:15:23: warning: suggest parentheses around '-' in operand of '&' [-Wparentheses]
   15 |  if (o >= 2 && (o & o - 1) == 0)
      |                     ~~^~~
arboras.c: In function 'main':
arboras.c:169:2: warning: ignoring return value of 'scanf' declared with attribute 'warn_unused_result' [-Wunused-result]
  169 |  scanf("%d", &n);
      |  ^~~~~~~~~~~~~~~
arboras.c:173:3: warning: ignoring return value of 'scanf' declared with attribute 'warn_unused_result' [-Wunused-result]
  173 |   scanf("%d", &pp[j]);
      |   ^~~~~~~~~~~~~~~~~~~
arboras.c:177:3: warning: ignoring return value of 'scanf' declared with attribute 'warn_unused_result' [-Wunused-result]
  177 |   scanf("%d", &ww[j]);
      |   ^~~~~~~~~~~~~~~~~~~
arboras.c:187:2: warning: ignoring return value of 'scanf' declared with attribute 'warn_unused_result' [-Wunused-result]
  187 |  scanf("%d", &q);
      |  ^~~~~~~~~~~~~~~
arboras.c:193:3: warning: ignoring return value of 'scanf' declared with attribute 'warn_unused_result' [-Wunused-result]
  193 |   scanf("%d%d", &j, &w);
      |   ^~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...