제출 #230792

#제출 시각아이디문제언어결과실행 시간메모리
230792walnutwaldo20바이러스 (JOI19_virus)C++14
100 / 100
610 ms85128 KiB
#include <bits/stdc++.h> #define F0R(i, a) for (int i = 0; i < (int)(a); i++) #define PB push_back #define MP make_pair #define F first #define S second using namespace std; typedef pair<int, int> pii; #define MAXN 640000 string dirchar = "NESW"; int dr[4]{ -1, 0, 1, 0 }; int dc[4]{ 0, 1, 0, -1 }; int m, r, c; int ss[MAXN]; int depth[MAXN], grouptop[MAXN]; int on[MAXN]; pii dfspar[MAXN]; int maxseq[16]; int u[800][800]; string s; int par[MAXN]; int nextnode[MAXN]; int lastnode[MAXN]; int memcounter = 0; int prevmemcounter; int codefor(pii loc) { return loc.F * c + loc.S; } int root(int node) { return (node == par[node]) ? node : par[node] = root(par[node]); } bool inBounds(pii loc) { return loc.F >= 0 && loc.F < r && loc.S >= 0 && loc.S < c && u[loc.F][loc.S] <= 100000; } bool infectedby(pii next, int comp) { int mask = 0; F0R(d, 4) { pii indir = MP(next.F + dr[d], next.S + dc[d]); if (inBounds(indir) && root(codefor(indir)) == root(comp)) { mask |= 1 << d; } } return maxseq[mask] >= u[next.F][next.S]; } vector<pii> adjToComp(int comp) { vector<pii> res; for (int curr = comp; curr != -1; curr = nextnode[curr]) { pii p = MP(curr / c, curr % c); F0R(d, 4) { pii next = MP(p.F + dr[d], p.S + dc[d]); if (inBounds(next) && root(codefor(next)) != root(comp)) { res.PB(next); memcounter += sizeof(next); } } } return res; } bool adjacentto(pii p, int comp) { F0R(d, 4) { pii next = MP(p.F + dr[d], p.S + dc[d]); if (inBounds(next) && root(codefor(next)) != root(comp)) { return true; } } return false; } void join(int a, int b, vector<pii>& q) { int r1 = root(a), r2 = root(b); if (r1 == r2) { return; } if (ss[r1] > ss[r2]) { swap(r1, r2); } vector<pii> adj = adjToComp(r1); par[r1] = r2; on[r2] += on[r1]; nextnode[lastnode[r2]] = r1; lastnode[r2] = lastnode[r1]; for (const pii p : adj) { if (root(codefor(p)) != r2 && infectedby(p, r2)) { q.PB(p); memcounter += sizeof(p); } } if (depth[grouptop[r1]] < depth[grouptop[r2]]) { grouptop[r2] = grouptop[r1]; } ss[r2] += ss[r1]; } void preprocess() { s += s; F0R(mask, 16) { int running = 0; F0R(i, s.size()) { int dcode = -1; F0R(j, 4) if (s[i] == dirchar[j]) { dcode = j; } if ((mask >> dcode) & 1) { running++; } else { running = 0; } maxseq[mask] = max(maxseq[mask], running); } if (maxseq[mask] == (int)s.size()) { maxseq[mask] = 100000; } } } pii comps[MAXN]; vector<pii> adjs[MAXN]; int stacksize = 0; void addtostack(pii newloc) { int code = codefor(newloc); depth[code] = stacksize; on[root(code)]++; comps[stacksize++] = newloc; F0R(d, 4) { pii next = MP(newloc.F + dr[d], newloc.S + dc[d]); if (inBounds(next) && root(codefor(next)) != root(code)) { if (infectedby(next, root(code))) { adjs[stacksize - 1].PB(next); memcounter += sizeof(next); } } } } void tarjan(pii startloc) { addtostack(startloc); while (stacksize) { pii node = comps[stacksize - 1]; if (adjs[stacksize - 1].empty()) { on[root(codefor(node))]--; stacksize--; } else { pii next = adjs[stacksize - 1].back(); adjs[stacksize - 1].pop_back(); if (root(codefor(next)) == root(codefor(node))) { continue; } if (depth[codefor(next)] != -1) { if (on[root(codefor(next))]) { int curr = grouptop[root(codefor(node))]; while (root(curr) != root(codefor(next))) { pii nextup = dfspar[curr]; join(curr, codefor(nextup), adjs[stacksize - 1]); curr = grouptop[root(codefor(nextup))]; } } } else { dfspar[codefor(next)] = node; addtostack(next); } } } } int main() { ios::sync_with_stdio(false); cin.tie(0); memcounter += sizeof(ss); memcounter += sizeof(depth); memcounter += sizeof(grouptop); memcounter += sizeof(on); memcounter += sizeof(dfspar); memcounter += 800 * 800 * sizeof(int); memcounter += sizeof(par); memcounter += sizeof(nextnode); memcounter += sizeof(lastnode); memcounter += sizeof(comps); memcounter += sizeof(adjs); cin >> m >> r >> c; cin >> s; F0R(i, r) F0R(j, c) { cin >> u[i][j]; if (u[i][j] == 0) { u[i][j] = INT_MAX; } } preprocess(); F0R(i, r) F0R(j, c) if (u[i][j] != INT_MAX) { int code = codefor(MP(i, j)); par[code] = code; ss[code] = 1; grouptop[code] = code; lastnode[code] = code; nextnode[code] = -1; } F0R(i, r) F0R(j, c) depth[codefor(MP(i, j))] = -1; F0R(i, r) F0R(j, c) if (u[i][j] != INT_MAX && depth[codefor(MP(i, j))] == -1) { tarjan(MP(i, j)); } pii res = MP(INT_MAX, 0); F0R(i, r) F0R(j, c) if (u[i][j] != INT_MAX) { pii loc = MP(i, j); if (codefor(loc) == root(codefor(loc))) { bool terminal = true; for (const pii p : adjToComp(codefor(loc))) { if (infectedby(p, codefor(loc))) { terminal = false; } } if (terminal) { int curr = ss[codefor(loc)]; if (curr == res.F) { res.S += curr; } else if (curr < res.F) { res = MP(curr, curr); } } } } cout << res.F << "\n" << res.S << endl; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...