Submission #1042408

#TimeUsernameProblemLanguageResultExecution timeMemory
1042408sleepntsheepInside information (BOI21_servers)C11
50 / 100
113 ms30404 KiB
/* WHAT IS EXTRA INFORAMZTION GTR RR */ #include <stdio.h> #include <stdlib.h> /* * 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) */ #define N 120001 #define B 300 int max(int i, int j) {return i > j ? i : j;} 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); } int Sq[N], Qs[N]; void build(int ii, int tme) { for (int i = 1; i <= n; ++i) dp[i] = 1, comp[i] = -1; for (int j = ii; j >= 0; --j) { int i = Sq[j]; if (qq[i].type[0] != 'S') continue; int x = dp[qq[i].a], y = dp[qq[i].b]; dp[qq[i].a] = max(dp[qq[i].a], y + 1); dp[qq[i].b] = max(dp[qq[i].b], x + 1); } for (int i = 1; i <= n; ++i) if (comp[i] == -1) efs(i, tme, i); } int counted[N]; int main() { scanf("%d%d", &n, &q); q = n + q - 1; for (int j = 0, i = 0; i < q; ++i) Qs[i] = -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); Sq[j++] = i; } else if (s[0] == 'Q') scanf("%d", &b); Qs[i] = j; 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 (Qs[i] - at % B == 0) { build(Qs[i], j); at = Qs[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 kk = at; kk <= Qs[i]; ++kk) { int k = Sq[kk]; 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 (stderr)

servers.c: In function 'pus_':
servers.c:31:26: warning: suggest parentheses around '-' in operand of '&' [-Wparentheses]
   31 |     else if (0 == (o & o - 1)) eh[i] = (int*)realloc(eh[i], 2 * o * sizeof **eh);
      |                        ~~^~~
servers.c: In function 'main':
servers.c:135:14: warning: unused variable 'j' [-Wunused-variable]
  135 |     for (int j = 0, i = 0; i < q; ++i)
      |              ^
servers.c:132:5: warning: ignoring return value of 'scanf' declared with attribute 'warn_unused_result' [-Wunused-result]
  132 |     scanf("%d%d", &n, &q);
      |     ^~~~~~~~~~~~~~~~~~~~~
servers.c:141:9: warning: ignoring return value of 'scanf' declared with attribute 'warn_unused_result' [-Wunused-result]
  141 |         scanf(" %s%d", s, &a);
      |         ^~~~~~~~~~~~~~~~~~~~~
servers.c:144:13: warning: ignoring return value of 'scanf' declared with attribute 'warn_unused_result' [-Wunused-result]
  144 |             scanf("%d", &b);
      |             ^~~~~~~~~~~~~~~
servers.c:148:13: warning: ignoring return value of 'scanf' declared with attribute 'warn_unused_result' [-Wunused-result]
  148 |             scanf("%d", &b);
      |             ^~~~~~~~~~~~~~~
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...