제출 #587399

#제출 시각아이디문제언어결과실행 시간메모리
587399GusterGoose27Flood (IOI07_flood)C++11
100 / 100
271 ms31612 KiB
#include <bits/stdc++.h> using namespace std; typedef pair<int, int> pii; const int MAXN = 1e5; const int MAXW = 2e5; int uf[2*MAXW]; // for vertical lines, left is +0, right is +w. For horizontal, bottom is +0, top is +w set<pii> active_points; char point_mask[MAXN]; // right, up, left, down pii points[MAXN]; int windex[MAXN][4]; int n, w; vector<int> edges[2*MAXW]; pii walls[MAXW]; vector<pii> w_edges[MAXN]; bool deact[MAXW]; vector<int> standing; int deg[MAXN]; int dist[2*MAXW]; int find(int i) { return (uf[i] == -1) ? i : (uf[i] = find(uf[i])); } void mask_add(int cur, int other, int w) { if (points[other].first > points[cur].first) { point_mask[cur] += 1; windex[cur][0] = w; } if (points[other].second > points[cur].second) { point_mask[cur] += 2; windex[cur][1] = w; } if (points[other].first < points[cur].first) { point_mask[cur] += 4; windex[cur][2] = w; } if (points[other].second < points[cur].second) { point_mask[cur] += 8; windex[cur][3] = w; } } int shift(int mask, int s) { int rshift = mask >> s; int lshift = mask % (1 << s); return (lshift << (4-s)) + rshift; } int get_cc(int i, int bit) { int base = windex[i][bit]; if (bit == 1 || bit == 2) return base; return base+w; } int get_cw(int i, int bit) { return (get_cc(i, bit)+w)%(2*w); } void prune(int cur) { deg[cur] = 0; for (pii next: w_edges[cur]) { if (deact[next.second]) continue; deact[next.second] = 1; deg[next.first]--; if (deg[next.first] == 1) prune(next.first); } } void bfs(int s) { dist[s] = 0; queue<int> q; q.push(s); while (!q.empty()) { int cur = q.front(); q.pop(); for (int next: edges[cur]) { if (dist[next] != -1) continue; dist[next] = dist[cur]+1; q.push(next); } } } int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); cin >> n; for (int i = 0; i < n; i++) { int x, y; cin >> x >> y; points[i] = pii(x, y); } cin >> w; fill(uf, uf+2*w, -1); for (int i = 0; i < w; i++) { int x, y; cin >> x >> y; x--; y--; walls[i] = pii(x, y); w_edges[x].push_back(pii(y, i)); w_edges[y].push_back(pii(x, i)); deg[x]++; deg[y]++; } for (int i = 0; i < n; i++) if (deg[i] == 1) prune(i); for (int i = 0; i < w; i++) { if (deact[i]) { standing.push_back(i); continue; } int x = walls[i].first; int y = walls[i].second; active_points.insert(pii(points[x].first, x)); active_points.insert(pii(points[y].first, y)); mask_add(x, y, i); mask_add(y, x, i); } for (pii p: active_points) { int i = p.second; for (int bit = 0; bit < 4; bit++) { if ((point_mask[i] & (1 << bit)) == 0) continue; int ccval = get_cc(i, bit); int maskcpy = shift(point_mask[i], bit+1); // shift to the right int nbit = log2(maskcpy&(-maskcpy)); nbit = (nbit+bit+1)%4; int cwval = get_cw(i, nbit); int ida = find(ccval); int idb = find(cwval); if (ida != idb) uf[ida] = idb; } } for (int i = 0; i < w; i++) { if (deact[i]) continue; int a = find(i); int b = find(w+i); //assert(a != b); // wouldve been deactivated if (a == b) continue; edges[a].push_back(b); edges[b].push_back(a); } fill(dist, dist+2*w, -1); for (pii p: active_points) { int i = p.second; int bit = log2(point_mask[i] & (-point_mask[i])); if (dist[find(get_cc(i, bit))] != -1) continue; assert((point_mask[i] & 2) || (point_mask[i] & 8)); if (point_mask[i] & 2) { int out = get_cc(i, 1); bfs(find(out)); } else { int out = get_cw(i, 3); bfs(find(out)); } } for (int i = 0; i < w; i++) { if (deact[i]) continue; int a = find(i); int b = find(w+i); if (dist[a] == dist[b]) standing.push_back(i); } cout << standing.size() << '\n'; for (int i: standing) cout << (i+1) << "\n"; return 0; }
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...