Submission #874420

#TimeUsernameProblemLanguageResultExecution timeMemory
874420sleepntsheepGrowing Trees (BOI11_grow)C++17
100 / 100
165 ms3456 KiB
#include <stdio.h> #include <algorithm> #define INLINE inline __attribute__((always_inline)) #define assert_(x) if (!(x)) __builtin_trap() #define N 100001 #include <random> #include <chrono> std::mt19937 rng(std::chrono::steady_clock::now().time_since_epoch().count()); unsigned seed = 0xcb1898af; INLINE unsigned rand_(void) { return (seed = (seed * 3)) >> 1; } int A[N], B[N], S[N], L[N], R[N], D[N], AT; INLINE int treap(int x) { A[++AT] = x; B[AT] = rand_(); S[AT] = 1; return AT; } INLINE void pull(int v) { S[v] = 1 + S[L[v]] + S[R[v]]; } INLINE void push(int v) { if (v && D[v]) { A[v] += D[v]; D[L[v]] += D[v]; D[R[v]] += D[v]; D[v] = 0; } } void spliti(int v, int *l, int *r, int ind) { if (!v) { *l=*r=0; return; } push(v); if (S[L[v]] < ind) { spliti(R[v], R+v, r, ind - S[L[v]] - 1); *l = v; } else { spliti(L[v], l, L+v, ind); *r = v; } pull(v); } void merge(int *v, int l, int r) { if (!l || !r) { *v = l^r; return; } push(l), push(r); if (B[l] < B[r]) { merge(L+r, l, L[r]); *v = r; } else { merge(R+l, R[l], r); *v = l; } pull(*v); } int order(int v, int k) { if (!v) return 0; push(v); if (A[v] < k) return 1 + S[L[v]] + order(R[v], k); return order(L[v], k); } int n, q, t; char op; INLINE int H(int v) { int c = v; while (R[c]) c = R[c]; return A[c]; } INLINE void fertilize(int s, int h) { int j = order(t, h); int y1 = 0, y2 = 0, y3 = 0, y4 = 0, y5 = 0, y6 = 0, y7 = 0, y8 = 0; spliti(t, &y1, &y2, j); spliti(y2, &y3, &y4, s); int x = H(y3); int aa = S[y3] - order(y3, x); int bb = order(y4, x+1); spliti(y3, &y5, &y6, S[y3] - aa); spliti(y4, &y7, &y8, bb); ++D[y5]; ++D[y6]; push(y5); push(y6); merge(&y4, y6, y8); merge(&y3, y5, y7); merge(&y2, y3, y4); merge(&t, y1, y2); } INLINE void query(int x, int y) { printf("%d\n", order(t, y+1) - order(t, x)); } int main(void) { scanf("%d%d", &n, &q); int a[N]; for (int i = 0; i < n; ++i) scanf("%d", a+i); std::sort(a, a+n); for (int i = 0; i < n; ++i) merge(&t, t, treap(a[i])); for (int x, y, i = 0; i < q; ++i) { scanf(" %c%d%d", &op, &x, &y); if (op == 'F') fertilize(x, y); else query(x, y); } return 0; }

Compilation message (stderr)

grow.cpp: In function 'int main()':
grow.cpp:130:10: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  130 |     scanf("%d%d", &n, &q);
      |     ~~~~~^~~~~~~~~~~~~~~~
grow.cpp:132:38: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  132 |     for (int i = 0; i < n; ++i) scanf("%d", a+i);
      |                                 ~~~~~^~~~~~~~~~~
grow.cpp:138:14: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  138 |         scanf(" %c%d%d", &op, &x, &y);
      |         ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...