답안 #1042508

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
1042508 2024-08-03T05:55:39 Z vjudge1 Inside information (BOI21_servers) C
100 / 100
1764 ms 27960 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 65 ms 8120 KB Output is correct
2 Correct 93 ms 8448 KB Output is correct
3 Correct 89 ms 8788 KB Output is correct
4 Correct 86 ms 8612 KB Output is correct
5 Correct 69 ms 8788 KB Output is correct
6 Correct 84 ms 8528 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 65 ms 8120 KB Output is correct
2 Correct 93 ms 8448 KB Output is correct
3 Correct 89 ms 8788 KB Output is correct
4 Correct 86 ms 8612 KB Output is correct
5 Correct 69 ms 8788 KB Output is correct
6 Correct 84 ms 8528 KB Output is correct
7 Correct 58 ms 8276 KB Output is correct
8 Correct 110 ms 8544 KB Output is correct
9 Correct 88 ms 8784 KB Output is correct
10 Correct 90 ms 8528 KB Output is correct
11 Correct 72 ms 8712 KB Output is correct
12 Correct 96 ms 8896 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 62 ms 8272 KB Output is correct
2 Correct 1122 ms 19064 KB Output is correct
3 Correct 1162 ms 19144 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 62 ms 8272 KB Output is correct
2 Correct 1122 ms 19064 KB Output is correct
3 Correct 1162 ms 19144 KB Output is correct
4 Correct 61 ms 8368 KB Output is correct
5 Correct 1262 ms 19048 KB Output is correct
6 Correct 1332 ms 19284 KB Output is correct
7 Correct 1533 ms 19536 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 58 ms 8276 KB Output is correct
2 Correct 928 ms 27552 KB Output is correct
3 Correct 930 ms 27728 KB Output is correct
4 Correct 433 ms 27480 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 58 ms 8276 KB Output is correct
2 Correct 928 ms 27552 KB Output is correct
3 Correct 930 ms 27728 KB Output is correct
4 Correct 433 ms 27480 KB Output is correct
5 Correct 62 ms 8272 KB Output is correct
6 Correct 1002 ms 27436 KB Output is correct
7 Correct 454 ms 27404 KB Output is correct
8 Correct 1052 ms 27604 KB Output is correct
9 Correct 1068 ms 27356 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 63 ms 8248 KB Output is correct
2 Correct 546 ms 18004 KB Output is correct
3 Correct 1175 ms 18336 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 63 ms 8248 KB Output is correct
2 Correct 546 ms 18004 KB Output is correct
3 Correct 1175 ms 18336 KB Output is correct
4 Correct 60 ms 8384 KB Output is correct
5 Correct 651 ms 18100 KB Output is correct
6 Correct 1281 ms 18040 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 58 ms 8276 KB Output is correct
2 Correct 940 ms 27960 KB Output is correct
3 Correct 936 ms 27472 KB Output is correct
4 Correct 415 ms 27484 KB Output is correct
5 Correct 58 ms 8276 KB Output is correct
6 Correct 602 ms 18000 KB Output is correct
7 Correct 1093 ms 18168 KB Output is correct
8 Correct 984 ms 19096 KB Output is correct
9 Correct 1065 ms 19024 KB Output is correct
10 Correct 1002 ms 21588 KB Output is correct
11 Correct 924 ms 20820 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 58 ms 8276 KB Output is correct
2 Correct 940 ms 27960 KB Output is correct
3 Correct 936 ms 27472 KB Output is correct
4 Correct 415 ms 27484 KB Output is correct
5 Correct 58 ms 8276 KB Output is correct
6 Correct 602 ms 18000 KB Output is correct
7 Correct 1093 ms 18168 KB Output is correct
8 Correct 984 ms 19096 KB Output is correct
9 Correct 1065 ms 19024 KB Output is correct
10 Correct 1002 ms 21588 KB Output is correct
11 Correct 924 ms 20820 KB Output is correct
12 Correct 55 ms 8576 KB Output is correct
13 Correct 979 ms 27464 KB Output is correct
14 Correct 450 ms 27600 KB Output is correct
15 Correct 1072 ms 27220 KB Output is correct
16 Correct 1035 ms 27312 KB Output is correct
17 Correct 62 ms 8276 KB Output is correct
18 Correct 645 ms 18004 KB Output is correct
19 Correct 1337 ms 18260 KB Output is correct
20 Correct 967 ms 19092 KB Output is correct
21 Correct 1159 ms 19028 KB Output is correct
22 Correct 1179 ms 20504 KB Output is correct
23 Correct 1262 ms 22064 KB Output is correct
24 Correct 1215 ms 21840 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 67 ms 8276 KB Output is correct
2 Correct 94 ms 8532 KB Output is correct
3 Correct 92 ms 8540 KB Output is correct
4 Correct 90 ms 8684 KB Output is correct
5 Correct 70 ms 8832 KB Output is correct
6 Correct 99 ms 8532 KB Output is correct
7 Correct 60 ms 8184 KB Output is correct
8 Correct 1140 ms 19004 KB Output is correct
9 Correct 1210 ms 19100 KB Output is correct
10 Correct 65 ms 8336 KB Output is correct
11 Correct 933 ms 27596 KB Output is correct
12 Correct 970 ms 27680 KB Output is correct
13 Correct 443 ms 27476 KB Output is correct
14 Correct 59 ms 8252 KB Output is correct
15 Correct 549 ms 18004 KB Output is correct
16 Correct 1071 ms 18032 KB Output is correct
17 Correct 902 ms 19032 KB Output is correct
18 Correct 986 ms 19232 KB Output is correct
19 Correct 1012 ms 21804 KB Output is correct
20 Correct 951 ms 20820 KB Output is correct
21 Correct 1078 ms 19024 KB Output is correct
22 Correct 1062 ms 19024 KB Output is correct
23 Correct 1281 ms 19444 KB Output is correct
24 Correct 1275 ms 19440 KB Output is correct
25 Correct 1660 ms 21328 KB Output is correct
26 Correct 1044 ms 18260 KB Output is correct
27 Correct 976 ms 18412 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 67 ms 8276 KB Output is correct
2 Correct 94 ms 8532 KB Output is correct
3 Correct 92 ms 8540 KB Output is correct
4 Correct 90 ms 8684 KB Output is correct
5 Correct 70 ms 8832 KB Output is correct
6 Correct 99 ms 8532 KB Output is correct
7 Correct 60 ms 8184 KB Output is correct
8 Correct 1140 ms 19004 KB Output is correct
9 Correct 1210 ms 19100 KB Output is correct
10 Correct 65 ms 8336 KB Output is correct
11 Correct 933 ms 27596 KB Output is correct
12 Correct 970 ms 27680 KB Output is correct
13 Correct 443 ms 27476 KB Output is correct
14 Correct 59 ms 8252 KB Output is correct
15 Correct 549 ms 18004 KB Output is correct
16 Correct 1071 ms 18032 KB Output is correct
17 Correct 902 ms 19032 KB Output is correct
18 Correct 986 ms 19232 KB Output is correct
19 Correct 1012 ms 21804 KB Output is correct
20 Correct 951 ms 20820 KB Output is correct
21 Correct 1078 ms 19024 KB Output is correct
22 Correct 1062 ms 19024 KB Output is correct
23 Correct 1281 ms 19444 KB Output is correct
24 Correct 1275 ms 19440 KB Output is correct
25 Correct 1660 ms 21328 KB Output is correct
26 Correct 1044 ms 18260 KB Output is correct
27 Correct 976 ms 18412 KB Output is correct
28 Correct 64 ms 8276 KB Output is correct
29 Correct 119 ms 8432 KB Output is correct
30 Correct 100 ms 8784 KB Output is correct
31 Correct 113 ms 8532 KB Output is correct
32 Correct 70 ms 8788 KB Output is correct
33 Correct 85 ms 8616 KB Output is correct
34 Correct 60 ms 8156 KB Output is correct
35 Correct 1216 ms 19172 KB Output is correct
36 Correct 1316 ms 19284 KB Output is correct
37 Correct 1475 ms 19204 KB Output is correct
38 Correct 56 ms 8216 KB Output is correct
39 Correct 984 ms 27476 KB Output is correct
40 Correct 445 ms 27472 KB Output is correct
41 Correct 1027 ms 27488 KB Output is correct
42 Correct 1036 ms 27228 KB Output is correct
43 Correct 74 ms 8252 KB Output is correct
44 Correct 665 ms 18000 KB Output is correct
45 Correct 1357 ms 18116 KB Output is correct
46 Correct 974 ms 19044 KB Output is correct
47 Correct 1192 ms 18988 KB Output is correct
48 Correct 1137 ms 20748 KB Output is correct
49 Correct 1280 ms 22100 KB Output is correct
50 Correct 1257 ms 21852 KB Output is correct
51 Correct 1328 ms 19280 KB Output is correct
52 Correct 1444 ms 19284 KB Output is correct
53 Correct 1523 ms 19144 KB Output is correct
54 Correct 1299 ms 19344 KB Output is correct
55 Correct 1413 ms 19284 KB Output is correct
56 Correct 1401 ms 19552 KB Output is correct
57 Correct 1764 ms 20924 KB Output is correct
58 Correct 1274 ms 18260 KB Output is correct
59 Correct 981 ms 18548 KB Output is correct