답안 #1042506

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
1042506 2024-08-03T05:52:51 Z sleepntsheep Inside information (BOI21_servers) C
100 / 100
1707 ms 27588 KB
#include <stdio.h>
#include <stdlib.h>

int max(int i, int j) { return i > j ? i : j; }
/*
 * For "Q" queries, use LCA + prefix sum on tree ~ 3O(lgn) [for finding lca and almost-lca]
 *
 * Every B queries of any type, do naive dp on tree (reverse edge order)
 * to find answer for "C" queries  ~ O(n)
 *
 * On "C" queries, use cached answer from above and count all edges that appeared after that (by "Q")
 * ~ O(B lgn)
 *
 *
 * Time complexity = O(N^2 / B) + O(N lgn) + O(N B lgn)
 *
 * Let B = sqrt(N / lgN)
 *
 * Should be able to optimize to O(N^1.5) using https://codeforces.com/blog/entry/71567?mobile=true&locale=en 
 */

#define N 120001
#define B 100

int n, q, pp[N], dd[N], up[N], temp, inc[N], tin[N], timer, hld[N], ds[N], sz[N], dp[N], counted[N];

int ds_find(int i) { return ds[i] == i ? i : (ds[i] = ds_find(ds[i])); }

void pus_(int **eh, int *eo, int i, int j) {
  int o = eo[i]++;
  if (0 == o) eh[i] = (int*)malloc(2 * sizeof **eh);
  else if (0 == (o & o - 1)) eh[i] = (int*)realloc(eh[i], 2 * o * sizeof **eh);
  eh[i][o] = j;
}

int *eh[N], *fh[N], eo[N];

void link(int u, int v, int w) {
  pus_(eh, eo, u, v);
  --eo[u];
  pus_(fh, eo, u, w);
  pus_(eh, eo, v, u);
  --eo[v];
  pus_(fh, eo, v, w);
}

void dfs(int u, int p) {
  sz[u] = 1;
  inc[u] = (up[u] > up[p]) + inc[p];
  for (int j = 0; j < eo[u]; ++j) if (eh[u][j] != p) {
    int v = eh[u][j];
    dd[v] = dd[u] + 1;
    pp[v] = u;
    up[v] = fh[u][j];
    dfs(v, u);
    sz[u] += sz[v];
  }

  for (int j = 0; j < eo[u]; ++j) if (eh[u][j] == p) { /* remove parent from adj */
    int ww = fh[u][j];
    for (int k = j + 1; k < eo[u]; ++k)
      eh[u][k - 1] = eh[u][k], fh[u][k - 1] = fh[u][k];
    --eo[u];
    break;
  }

  for (int j = 0; j < eo[u]; ++j) { /* hld prep */
    int v = eh[u][j];
    if (sz[v] > sz[eh[u][0]]) {
      temp = eh[u][0], eh[u][0] = v, eh[u][j] = temp;
      temp = fh[u][0], fh[u][0] = fh[u][j], fh[u][j] = temp;
    }
  }
}

void efs(int u, int hd) {
  tin[u] = timer++;
  hld[u] = hd;
  for (int j = 0; j < eo[u]; ++j)
    efs(eh[u][j], j ? eh[u][j] : hd);
}

int lca(int u, int v) {
  while (hld[u] != hld[v])
    if (dd[hld[u]] >= dd[hld[v]]) u = pp[hld[u]];
    else v = pp[hld[v]];
  return dd[u] <= dd[v] ? u : v;
}

struct Query {
  char type[2];
  int a, b;
} qq[N * 2];

int navigate(int u, int v) {
  int lb = -1, ub = eo[u];
  while (ub-lb>1){
    int md=lb+(ub-lb)/2;
    if(tin[eh[u][md]]<=tin[v])lb=md;
    else ub=md;
  }
  return eh[u][lb];
}

/* u = data node, v = ask node */
int query_yesno(int u, int v, int time) {
  if (u == v) return 1;
  int a = lca(u, v), va, ua;

  if (u == a) {
    va = navigate(a, v);
    return inc[v] - inc[va] == dd[v] - dd[va] && up[v] <= time;
  }
  if (v == a) {
    ua = navigate(a, u);
    return inc[u] - inc[ua] == 0 && up[ua] <= time;
  }

  ua = navigate(a, u);
  va = navigate(a, v);
  return (dd[v] - dd[va] == inc[v] - inc[va]) && (inc[u] - inc[ua] == 0)
    && up[va] > up[ua] && up[v] <= time;
}

void build(int ii, int tme) {
  for (int i = 1; i <= n; ++i) dp[i] = 1, ds_find(i);
  for (int i = ii; i >= 0; --i)
    if (qq[i].type[0] == 'S') {
      int x = dp[qq[i].a], y = dp[qq[i].b];
      dp[qq[i].a] += y;
      dp[qq[i].b] += x;
    }
}

int main() {
  scanf("%d%d", &n, &q);
  for (int i = 1; i <= n; ++i) ds[i] = i;

  q = n + q - 1;
  for (int j = 0, i = 0; i < q; ++i) {
    scanf(" %s%d", qq[i].type, &qq[i].a);
    if (qq[i].type[0] == 'S') {
      scanf("%d", &qq[i].b);
      link(qq[i].a, qq[i].b, j++);
    } else if (qq[i].type[0] == 'Q')
      scanf("%d", &qq[i].b);
  }

  up[1] = 1e9;
  pp[1] = 1;
  dfs(1, 1);
  efs(1, 1);

  build(-1, -1);
  int at = 0;

  for (int j = 0, i = 0; i < q; ++i) {
    if (qq[i].type[0] == 'S')
      ++j;

    if (i % B == 0) {
      for (int k = at; k <= i; ++k)
        if (qq[k].type[0] == 'S')
          ds[ds_find(qq[k].a)] = qq[k].b;
      build(i, j - 1);
      at = i + 1;
    }

    if (qq[i].type[0] == 'Q')
      puts(query_yesno(qq[i].b, qq[i].a, j - 1) ? "yes": "no");
    else if (qq[i].type[0] == 'C') {
      int addition = 0;
      for (int k = at; k < i; ++k)
        if (qq[k].type[0] == 'S') {
          int a[2] = {qq[k].a, qq[k].b};

          for (int ii = 0; ii < 2; ++ii)
            if (counted[a[ii]] != i + 1 &&
                ds_find(a[ii]) != ds_find(qq[i].a) && query_yesno(qq[i].a, a[ii], j - 1))
              ++addition, counted[a[ii]] = i + 1;
        }
      printf("%d\n", dp[qq[i].a] + addition);
    }
  }
}

Compilation message

servers.c: In function 'pus_':
servers.c:32:24: warning: suggest parentheses around '-' in operand of '&' [-Wparentheses]
   32 |   else if (0 == (o & o - 1)) eh[i] = (int*)realloc(eh[i], 2 * o * sizeof **eh);
      |                      ~~^~~
servers.c: In function 'dfs':
servers.c:60:9: warning: unused variable 'ww' [-Wunused-variable]
   60 |     int ww = fh[u][j];
      |         ^~
servers.c: In function 'main':
servers.c:136:3: warning: ignoring return value of 'scanf' declared with attribute 'warn_unused_result' [-Wunused-result]
  136 |   scanf("%d%d", &n, &q);
      |   ^~~~~~~~~~~~~~~~~~~~~
servers.c:141:5: warning: ignoring return value of 'scanf' declared with attribute 'warn_unused_result' [-Wunused-result]
  141 |     scanf(" %s%d", qq[i].type, &qq[i].a);
      |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
servers.c:143:7: warning: ignoring return value of 'scanf' declared with attribute 'warn_unused_result' [-Wunused-result]
  143 |       scanf("%d", &qq[i].b);
      |       ^~~~~~~~~~~~~~~~~~~~~
servers.c:146:7: warning: ignoring return value of 'scanf' declared with attribute 'warn_unused_result' [-Wunused-result]
  146 |       scanf("%d", &qq[i].b);
      |       ^~~~~~~~~~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 62 ms 8204 KB Output is correct
2 Correct 92 ms 8500 KB Output is correct
3 Correct 92 ms 8532 KB Output is correct
4 Correct 89 ms 8724 KB Output is correct
5 Correct 68 ms 8792 KB Output is correct
6 Correct 82 ms 8524 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 62 ms 8204 KB Output is correct
2 Correct 92 ms 8500 KB Output is correct
3 Correct 92 ms 8532 KB Output is correct
4 Correct 89 ms 8724 KB Output is correct
5 Correct 68 ms 8792 KB Output is correct
6 Correct 82 ms 8524 KB Output is correct
7 Correct 58 ms 8276 KB Output is correct
8 Correct 102 ms 8532 KB Output is correct
9 Correct 107 ms 8788 KB Output is correct
10 Correct 93 ms 8532 KB Output is correct
11 Correct 70 ms 8816 KB Output is correct
12 Correct 86 ms 8792 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 59 ms 8188 KB Output is correct
2 Correct 1184 ms 19128 KB Output is correct
3 Correct 1176 ms 19104 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 59 ms 8188 KB Output is correct
2 Correct 1184 ms 19128 KB Output is correct
3 Correct 1176 ms 19104 KB Output is correct
4 Correct 62 ms 8156 KB Output is correct
5 Correct 1237 ms 19032 KB Output is correct
6 Correct 1427 ms 19280 KB Output is correct
7 Correct 1488 ms 19416 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 56 ms 8272 KB Output is correct
2 Correct 990 ms 27472 KB Output is correct
3 Correct 969 ms 27472 KB Output is correct
4 Correct 420 ms 27488 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 56 ms 8272 KB Output is correct
2 Correct 990 ms 27472 KB Output is correct
3 Correct 969 ms 27472 KB Output is correct
4 Correct 420 ms 27488 KB Output is correct
5 Correct 102 ms 8272 KB Output is correct
6 Correct 1054 ms 27476 KB Output is correct
7 Correct 459 ms 27476 KB Output is correct
8 Correct 1074 ms 27176 KB Output is correct
9 Correct 1061 ms 27216 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 58 ms 8272 KB Output is correct
2 Correct 556 ms 18068 KB Output is correct
3 Correct 1188 ms 18048 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 58 ms 8272 KB Output is correct
2 Correct 556 ms 18068 KB Output is correct
3 Correct 1188 ms 18048 KB Output is correct
4 Correct 58 ms 8272 KB Output is correct
5 Correct 672 ms 18056 KB Output is correct
6 Correct 1366 ms 18084 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 55 ms 8272 KB Output is correct
2 Correct 967 ms 27412 KB Output is correct
3 Correct 983 ms 27588 KB Output is correct
4 Correct 448 ms 27292 KB Output is correct
5 Correct 71 ms 8324 KB Output is correct
6 Correct 592 ms 18096 KB Output is correct
7 Correct 1173 ms 18028 KB Output is correct
8 Correct 901 ms 19000 KB Output is correct
9 Correct 1016 ms 19336 KB Output is correct
10 Correct 1024 ms 21560 KB Output is correct
11 Correct 968 ms 20964 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 55 ms 8272 KB Output is correct
2 Correct 967 ms 27412 KB Output is correct
3 Correct 983 ms 27588 KB Output is correct
4 Correct 448 ms 27292 KB Output is correct
5 Correct 71 ms 8324 KB Output is correct
6 Correct 592 ms 18096 KB Output is correct
7 Correct 1173 ms 18028 KB Output is correct
8 Correct 901 ms 19000 KB Output is correct
9 Correct 1016 ms 19336 KB Output is correct
10 Correct 1024 ms 21560 KB Output is correct
11 Correct 968 ms 20964 KB Output is correct
12 Correct 94 ms 8272 KB Output is correct
13 Correct 989 ms 27364 KB Output is correct
14 Correct 528 ms 27416 KB Output is correct
15 Correct 1047 ms 27348 KB Output is correct
16 Correct 1052 ms 27240 KB Output is correct
17 Correct 57 ms 8276 KB Output is correct
18 Correct 710 ms 18004 KB Output is correct
19 Correct 1283 ms 18004 KB Output is correct
20 Correct 958 ms 19096 KB Output is correct
21 Correct 1150 ms 19024 KB Output is correct
22 Correct 1101 ms 20776 KB Output is correct
23 Correct 1280 ms 22096 KB Output is correct
24 Correct 1241 ms 21836 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 57 ms 8304 KB Output is correct
2 Correct 95 ms 8540 KB Output is correct
3 Correct 87 ms 8528 KB Output is correct
4 Correct 86 ms 8540 KB Output is correct
5 Correct 78 ms 8816 KB Output is correct
6 Correct 94 ms 8560 KB Output is correct
7 Correct 68 ms 8276 KB Output is correct
8 Correct 1106 ms 19028 KB Output is correct
9 Correct 1114 ms 19024 KB Output is correct
10 Correct 56 ms 8256 KB Output is correct
11 Correct 958 ms 27588 KB Output is correct
12 Correct 968 ms 27476 KB Output is correct
13 Correct 431 ms 27476 KB Output is correct
14 Correct 61 ms 8272 KB Output is correct
15 Correct 536 ms 17888 KB Output is correct
16 Correct 1079 ms 18004 KB Output is correct
17 Correct 912 ms 19024 KB Output is correct
18 Correct 1049 ms 19284 KB Output is correct
19 Correct 1006 ms 21748 KB Output is correct
20 Correct 924 ms 20948 KB Output is correct
21 Correct 1051 ms 19016 KB Output is correct
22 Correct 1044 ms 19028 KB Output is correct
23 Correct 1266 ms 19536 KB Output is correct
24 Correct 1301 ms 19540 KB Output is correct
25 Correct 1594 ms 21192 KB Output is correct
26 Correct 1109 ms 18212 KB Output is correct
27 Correct 947 ms 18512 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 57 ms 8304 KB Output is correct
2 Correct 95 ms 8540 KB Output is correct
3 Correct 87 ms 8528 KB Output is correct
4 Correct 86 ms 8540 KB Output is correct
5 Correct 78 ms 8816 KB Output is correct
6 Correct 94 ms 8560 KB Output is correct
7 Correct 68 ms 8276 KB Output is correct
8 Correct 1106 ms 19028 KB Output is correct
9 Correct 1114 ms 19024 KB Output is correct
10 Correct 56 ms 8256 KB Output is correct
11 Correct 958 ms 27588 KB Output is correct
12 Correct 968 ms 27476 KB Output is correct
13 Correct 431 ms 27476 KB Output is correct
14 Correct 61 ms 8272 KB Output is correct
15 Correct 536 ms 17888 KB Output is correct
16 Correct 1079 ms 18004 KB Output is correct
17 Correct 912 ms 19024 KB Output is correct
18 Correct 1049 ms 19284 KB Output is correct
19 Correct 1006 ms 21748 KB Output is correct
20 Correct 924 ms 20948 KB Output is correct
21 Correct 1051 ms 19016 KB Output is correct
22 Correct 1044 ms 19028 KB Output is correct
23 Correct 1266 ms 19536 KB Output is correct
24 Correct 1301 ms 19540 KB Output is correct
25 Correct 1594 ms 21192 KB Output is correct
26 Correct 1109 ms 18212 KB Output is correct
27 Correct 947 ms 18512 KB Output is correct
28 Correct 68 ms 8336 KB Output is correct
29 Correct 101 ms 8532 KB Output is correct
30 Correct 89 ms 8788 KB Output is correct
31 Correct 90 ms 8536 KB Output is correct
32 Correct 70 ms 8700 KB Output is correct
33 Correct 90 ms 8632 KB Output is correct
34 Correct 65 ms 8364 KB Output is correct
35 Correct 1213 ms 19004 KB Output is correct
36 Correct 1312 ms 19340 KB Output is correct
37 Correct 1461 ms 19224 KB Output is correct
38 Correct 66 ms 8116 KB Output is correct
39 Correct 993 ms 27472 KB Output is correct
40 Correct 450 ms 27464 KB Output is correct
41 Correct 1045 ms 27376 KB Output is correct
42 Correct 1000 ms 27216 KB Output is correct
43 Correct 58 ms 8328 KB Output is correct
44 Correct 631 ms 18004 KB Output is correct
45 Correct 1268 ms 18000 KB Output is correct
46 Correct 945 ms 19092 KB Output is correct
47 Correct 1158 ms 19040 KB Output is correct
48 Correct 1096 ms 20568 KB Output is correct
49 Correct 1240 ms 22168 KB Output is correct
50 Correct 1248 ms 21844 KB Output is correct
51 Correct 1295 ms 19240 KB Output is correct
52 Correct 1467 ms 19280 KB Output is correct
53 Correct 1478 ms 19256 KB Output is correct
54 Correct 1325 ms 19284 KB Output is correct
55 Correct 1419 ms 19264 KB Output is correct
56 Correct 1431 ms 19540 KB Output is correct
57 Correct 1707 ms 21032 KB Output is correct
58 Correct 1272 ms 18212 KB Output is correct
59 Correct 938 ms 18300 KB Output is correct