답안 #1042423

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
1042423 2024-08-03T04:20:04 Z sleepntsheep Inside information (BOI21_servers) C
65 / 100
3500 ms 26376 KB
/* WHAT IS EXTRA INFORAMZTION GTR RR */

#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 900

int n, q, pp[N], jj[N], dd[N], up[N], temp, inc[N];

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) {
    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;
        jj[v] = (dd[u] - dd[jj[u]] == dd[jj[u]] - dd[jj[jj[u]]]) ? jj[jj[u]]: u;
        up[v] = fh[u][j];
        dfs(v, u);
    }
}

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

int anc(int u, int dep) {
    while (dd[u] > dep)
        u = (dd[jj[u]] >= dep) ? jj[u] : pp[u];
    return u;
}

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

/* 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);
    int va, ua;
    ua = anc(u, dd[a] + 1);
    va = anc(v, dd[a] + 1);

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

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

int dp[N], comp[N];

void efs(int u, int time, int root) {
    comp[u] = root;
    for (int j = 0; j < eo[u]; ++j)
        if (fh[u][j] <= time && comp[eh[u][j]] == -1)
            efs(eh[u][j], time, root);
}

void build(int ii, int tme) {
    for (int i = 1; i <= n; ++i)
        dp[i] = 1, comp[i] = -1;
    for (int i = 1; i <= n; ++i)
        if (comp[i] == -1)
            efs(i, tme, i);

    for (int i = ii; i >= 0; --i) {
        if (qq[i].type[0] != 'S')
            continue;

        int x = dp[qq[i].a], y = dp[qq[i].b];
        dp[qq[i].a] += y;
        dp[qq[i].b] += x;
    }
}

int counted[N];

int main() {
    scanf("%d%d", &n, &q);

    q = n + q - 1;
    for (int j = 0, i = 0; i < q; ++i) {
        int a, b = 0;
        char *s = qq[i].type;

        scanf(" %s%d", s, &a);
        if (s[0] == 'S') {
            scanf("%d", &b);
            link(a, b, j++);
        } else if (s[0] == 'Q')
            scanf("%d", &b);

        qq[i].a = a, qq[i].b = b;
    }

    up[1] = 1e9;
    pp[1] = jj[1] = 1;
    dfs(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) {
            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 focus = qq[i].a;
            int addition = 0;
            for (int k = at; k < i; ++k)
                if (qq[k].type[0] == 'S') {
                    int a = qq[k].a, b = qq[k].b;

                    if (counted[a] != i + 1 &&
                            comp[a] != comp[focus] && query_yesno(focus, a, j - 1))
                        ++addition, counted[a] = i + 1;
                    if (counted[b] != i + 1 && 
                            comp[b] != comp[focus] && query_yesno(focus, b, j - 1))
                        ++addition, counted[b] = i + 1;
                }
            printf("%d\n", dp[focus] + addition);
        }
    }
}

Compilation message

servers.c: In function 'pus_':
servers.c:32:26: 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 'main':
servers.c:129:5: warning: ignoring return value of 'scanf' declared with attribute 'warn_unused_result' [-Wunused-result]
  129 |     scanf("%d%d", &n, &q);
      |     ^~~~~~~~~~~~~~~~~~~~~
servers.c:136:9: warning: ignoring return value of 'scanf' declared with attribute 'warn_unused_result' [-Wunused-result]
  136 |         scanf(" %s%d", s, &a);
      |         ^~~~~~~~~~~~~~~~~~~~~
servers.c:138:13: warning: ignoring return value of 'scanf' declared with attribute 'warn_unused_result' [-Wunused-result]
  138 |             scanf("%d", &b);
      |             ^~~~~~~~~~~~~~~
servers.c:141:13: warning: ignoring return value of 'scanf' declared with attribute 'warn_unused_result' [-Wunused-result]
  141 |             scanf("%d", &b);
      |             ^~~~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 22 ms 4696 KB Output is correct
2 Correct 38 ms 5276 KB Output is correct
3 Correct 29 ms 5200 KB Output is correct
4 Correct 62 ms 5200 KB Output is correct
5 Correct 64 ms 5456 KB Output is correct
6 Correct 26 ms 5204 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 22 ms 4696 KB Output is correct
2 Correct 38 ms 5276 KB Output is correct
3 Correct 29 ms 5200 KB Output is correct
4 Correct 62 ms 5200 KB Output is correct
5 Correct 64 ms 5456 KB Output is correct
6 Correct 26 ms 5204 KB Output is correct
7 Correct 22 ms 4700 KB Output is correct
8 Correct 103 ms 5020 KB Output is correct
9 Correct 58 ms 5204 KB Output is correct
10 Correct 275 ms 5084 KB Output is correct
11 Correct 163 ms 5712 KB Output is correct
12 Correct 51 ms 5312 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 22 ms 4700 KB Output is correct
2 Correct 357 ms 17744 KB Output is correct
3 Correct 330 ms 17588 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 22 ms 4700 KB Output is correct
2 Correct 357 ms 17744 KB Output is correct
3 Correct 330 ms 17588 KB Output is correct
4 Correct 24 ms 4952 KB Output is correct
5 Correct 493 ms 18004 KB Output is correct
6 Correct 587 ms 18516 KB Output is correct
7 Correct 674 ms 18360 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 24 ms 4696 KB Output is correct
2 Correct 630 ms 26196 KB Output is correct
3 Correct 645 ms 26088 KB Output is correct
4 Correct 294 ms 25996 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 24 ms 4696 KB Output is correct
2 Correct 630 ms 26196 KB Output is correct
3 Correct 645 ms 26088 KB Output is correct
4 Correct 294 ms 25996 KB Output is correct
5 Correct 24 ms 4700 KB Output is correct
6 Execution timed out 3548 ms 26320 KB Time limit exceeded
7 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 20 ms 4808 KB Output is correct
2 Correct 252 ms 16724 KB Output is correct
3 Correct 641 ms 16720 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 20 ms 4808 KB Output is correct
2 Correct 252 ms 16724 KB Output is correct
3 Correct 641 ms 16720 KB Output is correct
4 Correct 28 ms 4896 KB Output is correct
5 Correct 584 ms 17156 KB Output is correct
6 Correct 1370 ms 17144 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 21 ms 4700 KB Output is correct
2 Correct 637 ms 25996 KB Output is correct
3 Correct 613 ms 26052 KB Output is correct
4 Correct 288 ms 25936 KB Output is correct
5 Correct 19 ms 4696 KB Output is correct
6 Correct 244 ms 16720 KB Output is correct
7 Correct 667 ms 16672 KB Output is correct
8 Correct 810 ms 17700 KB Output is correct
9 Correct 636 ms 17748 KB Output is correct
10 Correct 636 ms 20168 KB Output is correct
11 Correct 769 ms 19540 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 21 ms 4700 KB Output is correct
2 Correct 637 ms 25996 KB Output is correct
3 Correct 613 ms 26052 KB Output is correct
4 Correct 288 ms 25936 KB Output is correct
5 Correct 19 ms 4696 KB Output is correct
6 Correct 244 ms 16720 KB Output is correct
7 Correct 667 ms 16672 KB Output is correct
8 Correct 810 ms 17700 KB Output is correct
9 Correct 636 ms 17748 KB Output is correct
10 Correct 636 ms 20168 KB Output is correct
11 Correct 769 ms 19540 KB Output is correct
12 Correct 26 ms 4696 KB Output is correct
13 Execution timed out 3571 ms 26376 KB Time limit exceeded
14 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 22 ms 4700 KB Output is correct
2 Correct 40 ms 5204 KB Output is correct
3 Correct 30 ms 5212 KB Output is correct
4 Correct 54 ms 5324 KB Output is correct
5 Correct 52 ms 5464 KB Output is correct
6 Correct 27 ms 5212 KB Output is correct
7 Correct 19 ms 4948 KB Output is correct
8 Correct 331 ms 17600 KB Output is correct
9 Correct 318 ms 17744 KB Output is correct
10 Correct 20 ms 4800 KB Output is correct
11 Correct 596 ms 26192 KB Output is correct
12 Correct 602 ms 26156 KB Output is correct
13 Correct 298 ms 26196 KB Output is correct
14 Correct 20 ms 4700 KB Output is correct
15 Correct 253 ms 16724 KB Output is correct
16 Correct 674 ms 16720 KB Output is correct
17 Correct 815 ms 17772 KB Output is correct
18 Correct 692 ms 17824 KB Output is correct
19 Correct 634 ms 20048 KB Output is correct
20 Correct 776 ms 19536 KB Output is correct
21 Correct 332 ms 17796 KB Output is correct
22 Correct 336 ms 17744 KB Output is correct
23 Correct 419 ms 18256 KB Output is correct
24 Correct 406 ms 18112 KB Output is correct
25 Correct 655 ms 19796 KB Output is correct
26 Correct 992 ms 16892 KB Output is correct
27 Correct 992 ms 16948 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 22 ms 4700 KB Output is correct
2 Correct 40 ms 5204 KB Output is correct
3 Correct 30 ms 5212 KB Output is correct
4 Correct 54 ms 5324 KB Output is correct
5 Correct 52 ms 5464 KB Output is correct
6 Correct 27 ms 5212 KB Output is correct
7 Correct 19 ms 4948 KB Output is correct
8 Correct 331 ms 17600 KB Output is correct
9 Correct 318 ms 17744 KB Output is correct
10 Correct 20 ms 4800 KB Output is correct
11 Correct 596 ms 26192 KB Output is correct
12 Correct 602 ms 26156 KB Output is correct
13 Correct 298 ms 26196 KB Output is correct
14 Correct 20 ms 4700 KB Output is correct
15 Correct 253 ms 16724 KB Output is correct
16 Correct 674 ms 16720 KB Output is correct
17 Correct 815 ms 17772 KB Output is correct
18 Correct 692 ms 17824 KB Output is correct
19 Correct 634 ms 20048 KB Output is correct
20 Correct 776 ms 19536 KB Output is correct
21 Correct 332 ms 17796 KB Output is correct
22 Correct 336 ms 17744 KB Output is correct
23 Correct 419 ms 18256 KB Output is correct
24 Correct 406 ms 18112 KB Output is correct
25 Correct 655 ms 19796 KB Output is correct
26 Correct 992 ms 16892 KB Output is correct
27 Correct 992 ms 16948 KB Output is correct
28 Correct 22 ms 4776 KB Output is correct
29 Correct 101 ms 5200 KB Output is correct
30 Correct 63 ms 5204 KB Output is correct
31 Correct 274 ms 5072 KB Output is correct
32 Correct 155 ms 5460 KB Output is correct
33 Correct 51 ms 5468 KB Output is correct
34 Correct 24 ms 4836 KB Output is correct
35 Correct 406 ms 18260 KB Output is correct
36 Correct 557 ms 18516 KB Output is correct
37 Correct 689 ms 18512 KB Output is correct
38 Correct 26 ms 4696 KB Output is correct
39 Execution timed out 3548 ms 26168 KB Time limit exceeded
40 Halted 0 ms 0 KB -