Submission #1165679

#TimeUsernameProblemLanguageResultExecution timeMemory
1165679SmuggingSpunPainting Walls (APIO20_paint)C++20
100 / 100
258 ms14784 KiB
#include<bits/stdc++.h> #include "paint.h" using namespace std; const int INF = 1e9; template<class T>void minimize(T& a, T b){ if(a > b){ a = b; } } template<class T>void maximize(T& a, T b){ if(a < b){ a = b; } } int minimumInstructions(int n, int m, int k, vector<int>c, vector<int>a, vector<vector<int>>b){ bool is_sub1 = true; auto pre_check = [&] (){ vector<int>cnt(k, 0); for(int i = 0; i < m; i++){ for(int& j : b[i]){ if(cnt[j]++ == 1){ is_sub1 = false; return; } } } }; pre_check(); if(is_sub1){ vector<int>to(k, -2); for(int i = 0; i < m; i++){ for(int& j : b[i]){ to[j] = i; } } int cnt = 1, ans = 0, pre = to[c[0]]; for(int i = 1; i < n; i++, cnt++){ if(cnt == m){ cnt = 0; if((pre = to[c[i]]) == -2){ return -1; } ans++; } else if(to[c[i]] != (pre = (pre + 1) % m)){ return -1; } } return ans + 1; } if(n <= 20000 && m <= 2000){ vector<vector<int>>p(k); for(int i = 0; i < n; i++){ p[c[i]].emplace_back(i); } vector<vector<bool>>can(m, vector<bool>(n, false)); for(int i = 0; i < m; i++){ for(int& j : b[i]){ for(int& k : p[j]){ can[i][k] = true; } } } vector<bool>paint(n, false); for(int i = 0; i + m <= n; i++){ for(int j = 0; j < m; j++){ bool flag = true; for(int k = 0; k < m; k++){ if(!can[(j + k) % m][i + k]){ flag = false; break; } } if(flag){ paint[i] = true; break; } } } vector<int>dp(n + 1, INF); dp[n] = 0; for(int i = n - 1; i > -1; dp[i--]++){ for(int j = min(i, n - m); j >= max(0, i - m + 1); j--){ if(paint[j]){ for(int k = i; k < j + m; k++){ minimize(dp[i], dp[k + 1]); } break; } } } return dp[0] >= INF ? -1 : dp[0]; } vector<vector<int>>ins(k); for(int i = 0; i < m; i++){ for(int& j : b[i]){ ins[j].emplace_back(i); } } vector<int>f(n, 0); vector<pair<int, int>>state; for(int& i : ins[c[0]]){ state.emplace_back(i, 1); } f[0] = int(!state.empty()); for(int i = 1; i < n; i++){ vector<pair<int, int>>nxt_state; for(int& j : ins[c[i]]){ nxt_state.emplace_back(j, 1); } if(!nxt_state.empty()){ nxt_state.emplace_back(nxt_state[0]); nxt_state.back().first += m; int ptr = 0; for(auto& [p, v] : state){ while(nxt_state[ptr].first <= p){ ptr++; } if(nxt_state[ptr].first == p + 1){ nxt_state[ptr].second = v + 1; } } maximize(nxt_state[0].second, nxt_state.back().second); nxt_state.pop_back(); } swap(state, nxt_state); for(auto& [foo, v] : state){ maximize(f[i], v); } } vector<bool>paint(n, false); for(int i = 0; i < n; i++){ if(f[i] >= m){ paint[i - m + 1] = true; } } vector<int>left(n, -1); if(paint[0]){ left[0] = 0; } for(int i = 1; i < n; i++){ left[i] = (paint[i] ? i : left[i - 1]); } vector<int>st((n + 1) << 2, INF); function<void(int, int)>update; update = [&] (int p, int x){ int id = 1, l = 0, r = n; while(l < r){ minimize(st[id], x); int m = (l + r) >> 1; id <<= 1; if(m < p){ l = m + 1; id |= 1; } else{ r = m; } } st[id] = x; }; function<int(int, int, int, int, int)>get; get = [&] (int id, int l, int r, int u, int v){ if(l > v || r < u){ return INF; } if(u <= l && v >= r){ return st[id]; } int m = (l + r) >> 1; return min(get(id << 1, l, m, u, v), get(id << 1 | 1, m + 1, r, u, v)); }; update(n, 0); for(int i = n - 1; i > -1; i--){ if(left[i] >= max(0, i - m + 1)){ update(i, get(1, 0, n, i + 1, left[i] + m) + 1); } } int ans = get(1, 0, n, 0, 0); return ans >= INF ? -1 : ans; }
#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...