제출 #560810

#제출 시각아이디문제언어결과실행 시간메모리
560810nghiass001벽 칠하기 (APIO20_paint)C++17
12 / 100
180 ms47312 KiB
#include <bits/stdc++.h> #include <ext/pb_ds/assoc_container.hpp> #include <ext/pb_ds/tree_policy.hpp> #define FOR(i,l,r) for(int i=(l); i<=(r); ++i) #define REP(i,l,r) for(int i=(l); i<(r); ++i) #define FORD(i,r,l) for(int i=(r); i>=(l); --i) #define REPD(i,r,l) for(int i=(r)-1; i>=(l); --i) using namespace std; using namespace __gnu_pbds; template <class key, class value> using ordered_map = tree<key, value, less<key>, rb_tree_tag, tree_order_statistics_node_update>; const int N = 100005, maxM = 50005, logM = 16, maxK = 100005, INF = 0x3c3c3c3c; int kmp[maxM], kmp2[maxM], prefix[N], suffix[N], ans[N]; int p[maxM][logM]; vector<int> Q[maxK]; ordered_map<int, int> M[maxM], M_next[maxM]; int minimumInstructions(int n, int m, int k, vector<int> C, vector<int> A, vector<vector<int>> B) { C.insert(C.begin(), -1); A.insert(A.begin(), 0); B.insert(B.begin(), vector<int>()); FOR(i, 1, m) { for(int v : B[i]) { Q[v].push_back(i); M[i][v] = 1; } } FOR(i, 1, k) { for(int u : Q[i]) for(int v : Q[i]) M_next[u][v] = 1; } /// all about kmp kmp[0] = -1; FOR(i, 2, m) { for(int j = kmp[i - 1]; j != -1; j = kmp[j]) { if (M_next[i][j + 1]) { kmp[i] = j + 1; break; } } } prefix[0] = 0; FOR(i, 1, n) { for(int j = prefix[i - 1]; j != -1; j = kmp[j]) { if (M[j + 1][C[i]]) { prefix[i] = j + 1; break; } } } kmp2[m + 1] = m + 2; kmp2[m] = m + 1; FORD(i, m - 1, 1) { kmp2[i] = m + 1; for(int j = kmp2[i + 1]; j != m + 2; j = kmp2[j]) { if (M_next[i][j - 1]) { kmp2[i] = j - 1; break; } } } suffix[n + 1] = m + 1; FORD(i, n, 1) { suffix[i] = m + 1; for(int j = suffix[i + 1]; j != m + 2; j = kmp2[j]) { if (M[j - 1][C[i]]) { suffix[i] = j - 1; break; } } } /// build FOR(i, 1, m) p[i][0] = kmp[i]; REP(j, 1, logM) FOR(i, 1, m) p[i][j] = p[p[i][j - 1]][j - 1]; /// solve FOR(i, 1, m - 1) ans[i] = INF; FOR(i, m, n) { ans[i] = INF; int vx = prefix[i]; int hope = suffix[i - m + 1] - 1; REPD(j, logM, 0) if (p[vx][j] >= hope) vx = p[vx][j]; if (vx == hope) { ans[i] = ans[i - m] + 1; } FORD(j, i - 1, i - m) { if (ans[j] > ans[i]) ans[j] = ans[i]; else break; } } if (ans[n] >= INF) ans[n] = -1; return ans[n]; }
#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...