# | 제출 시각 | 아이디 | 문제 | 언어 | 결과 | 실행 시간 | 메모리 |
---|---|---|---|---|---|---|---|
100899 | 2019-03-15T03:57:48 Z | E869120 | 동기화 (JOI13_synchronization) | C++14 | 8000 ms | 38564 KB |
// クエリ平方分割 + bitset の (N^1.5 + N^2 / 64) で満点を狙う。 #include <bits/stdc++.h> using namespace std; const int Backet = 700; int N, M, A[200009], B[200009], X[200009], D1[200009], D2[200009], popcnt[1 << 22]; int num[200009], col[200009], colnum[200009], cnts, cntv; bool used[200009], used2[200009], used3[200009], v[200009]; vector<int> G1[200009], G2[200009]; unsigned long long ptr[300009]; void dfs(int pos) { col[pos] = cnts; for (int i : G1[pos]) { if (col[i] >= 1) continue; dfs(i); } } void dfs1(int pos, int rev) { colnum[pos] = rev; used3[pos] = true; for (int i : G2[pos]) { if (used3[i] == true) continue; dfs1(i, rev); } } void solve(int l, int r) { for (int i = 1; i <= N; i++) { col[i] = 0; colnum[i] = 0; G1[i].clear(); } for (int i = 1; i <= N - 1; i++) used2[i] = used[i]; for (int i = l; i <= r; i++) used2[X[i]] = false; for (int i = 1; i <= N - 1; i++) { if (used2[i] == false) continue; G1[A[i]].push_back(B[i]); G1[B[i]].push_back(A[i]); } cnts = 0; for (int i = 1; i <= N; i++) { if (col[i] >= 1) continue; cnts++; dfs(i); } for (int i = 1; i <= N; i++) colnum[col[i]] = num[i]; vector<int>E; for (int i = l; i <= r; i++) { E.push_back(col[A[X[i]]]); E.push_back(col[B[X[i]]]); } sort(E.begin(), E.end()); E.erase(unique(E.begin(), E.end()), E.end()); for (int i = l; i <= r; i++) { for (int j = 0; j < E.size(); j++) { used3[E[j]] = false; G2[E[j]].clear(); } // グラフに現在の辺を貼る for (int j = l; j <= i; j++) { bool e = used[X[j]]; if (X[j] == X[i]) e ^= true; if (e == false) continue; int pos = X[j]; G2[col[A[pos]]].push_back(col[B[pos]]); G2[col[B[pos]]].push_back(col[A[pos]]); } int pos = X[i]; if (used[pos] == false) { // 結合する場合 : D1 と D2 を結合して D1 にする D1[i] = colnum[col[A[pos]]]; D2[i] = colnum[col[B[pos]]]; dfs1(col[A[pos]], D1[i]); v[i] = false; } if (used[pos] == true) { // 分離する場合: D1 を D2 にコピーする D1[i] = colnum[col[A[pos]]]; D2[i] = cntv + 1; cntv++; dfs1(col[B[pos]], cntv); v[i] = true; } used[pos] ^= true; } for (int i = 1; i <= N; i++) num[i] = colnum[col[i]]; } void init() { for (int i = 0; i < (1 << 22); i++) popcnt[i] = __builtin_popcount(i); } int ans[100009]; int main() { int Q; scanf("%d%d%d", &N, &M, &Q); for (int i = 1; i <= N - 1; i++) { scanf("%d%d", &A[i], &B[i]); } for (int i = 1; i <= M; i++) { scanf("%d", &X[i]); } for (int i = 1; i <= N; i++) num[i] = i; cntv = N; // クエリ平方分割パート for (int i = 1; i <= M; i += Backet) { int L = i, R = i + Backet - 1; if (R > M) R = M; solve(L, R); } // ビットセットパート int BASE = 32; init(); for (int i = 1; i <= N; i += BASE) { int L = i, R = i + (BASE - 1); if (R >= N) R = N; for (int j = 1; j <= cntv; j++) ptr[j] = 0; for (int j = L; j <= R; j++) ptr[j] += (1ULL << (j - L)); for (int j = 1; j <= M; j++) { if (v[j] == false) ptr[D1[j]] |= ptr[D2[j]]; if (v[j] == true) ptr[D2[j]] = ptr[D1[j]]; } for (int j = 1; j <= N; j++) { unsigned long long E = ptr[num[j]]; ans[j] += popcnt[E & 4194303]; E >>= 22; ans[j] += popcnt[E & 4194303]; E >>= 22; ans[j] += popcnt[E]; } } for (int j = 1; j <= Q; j++) { int cc; scanf("%d", &cc); printf("%d\n", ans[cc]); } return 0; }
Compilation message
# | 결과 | 실행 시간 | 메모리 | Grader output |
---|---|---|---|---|
1 | Correct | 38 ms | 26232 KB | Output is correct |
2 | Correct | 39 ms | 26236 KB | Output is correct |
3 | Correct | 40 ms | 26220 KB | Output is correct |
4 | Correct | 38 ms | 26196 KB | Output is correct |
5 | Correct | 50 ms | 26232 KB | Output is correct |
6 | Correct | 47 ms | 26312 KB | Output is correct |
7 | Correct | 256 ms | 27496 KB | Output is correct |
8 | Correct | 295 ms | 27384 KB | Output is correct |
9 | Correct | 243 ms | 27512 KB | Output is correct |
10 | Execution timed out | 8074 ms | 38068 KB | Time limit exceeded |
11 | Halted | 0 ms | 0 KB | - |
# | 결과 | 실행 시간 | 메모리 | Grader output |
---|---|---|---|---|
1 | Correct | 3787 ms | 37512 KB | Output is correct |
2 | Correct | 3452 ms | 37392 KB | Output is correct |
3 | Incorrect | 2452 ms | 38564 KB | Output isn't correct |
4 | Halted | 0 ms | 0 KB | - |
# | 결과 | 실행 시간 | 메모리 | Grader output |
---|---|---|---|---|
1 | Correct | 37 ms | 26168 KB | Output is correct |
2 | Correct | 37 ms | 26232 KB | Output is correct |
3 | Correct | 38 ms | 26232 KB | Output is correct |
4 | Correct | 37 ms | 26288 KB | Output is correct |
5 | Correct | 43 ms | 26272 KB | Output is correct |
6 | Incorrect | 48 ms | 26364 KB | Output isn't correct |
7 | Halted | 0 ms | 0 KB | - |
# | 결과 | 실행 시간 | 메모리 | Grader output |
---|---|---|---|---|
1 | Execution timed out | 8007 ms | 38392 KB | Time limit exceeded |
2 | Halted | 0 ms | 0 KB | - |
# | 결과 | 실행 시간 | 메모리 | Grader output |
---|---|---|---|---|
1 | Correct | 43 ms | 26244 KB | Output is correct |
2 | Correct | 40 ms | 26232 KB | Output is correct |
3 | Correct | 39 ms | 26204 KB | Output is correct |
4 | Correct | 39 ms | 26240 KB | Output is correct |
5 | Incorrect | 46 ms | 26336 KB | Output isn't correct |
6 | Halted | 0 ms | 0 KB | - |