Submission #591698

#TimeUsernameProblemLanguageResultExecution timeMemory
591698kamelfanger83Paint By Numbers (IOI16_paint)C++14
59 / 100
1 ms296 KiB
#include "paint.h" #include <vector> #include <string> #include <functional> #include <limits> #include <algorithm> #include <cassert> using namespace std; struct segtree{ vector<int> cache; function<int(int, int)> conquer; int neutral; segtree(int n, function<int(int, int)> conquera, int neutrala){ cache = vector<int> (n*4); conquer = conquera; neutral = neutrala; } int build(int l, int r, int i, vector<int>& v){ if(l+1==r) return cache[i] = v[l]; int m = l + (r-l)/2; return cache[i] = conquer(build(l, m, i*2+1, v), build(m, r, i*2+2, v)); } int query(int l, int r, int i, int ql, int qr){ if(ql <= l && r <= qr) return cache[i]; if(qr <= l || r <= ql) return neutral; int m = l + (r-l)/2; return conquer(query(l, m, i*2+1, ql, qr), query(m, r, i*2+2, ql, qr)); } }; string solve_puzzle(string s, vector<int> c) { int k = c.size(); int n = s.size(); auto add = [&](int a, int b) ->int {return a + b;}; auto minf = [&](int a, int b) ->int {return min(a, b);}; segtree sum (k, add, 0); sum.build(0, k, 0, c); segtree mint (k, minf, numeric_limits<int>::max()); mint.build(0, k, 0, c); vector<int> back_cram = {k}; vector<int> occ = {n}; int tsize = 0; int at = k-1; for(int back = n-1; back >= 0; back--){ if(s[back] == '_'){ occ.push_back(back); while(at >= 0 && tsize >= c[at]){ tsize -= c[at] + 1; at--; } tsize = 0; back_cram.push_back(at+1); } else tsize++; } occ.push_back(-1); reverse(back_cram.begin(), back_cram.end()); reverse(occ.begin(), occ.end()); int maxdone = 0; int bi = 0; for(int solver = 0; solver < n; solver++){ if(s[solver] != '.'){ int tsize = occ[bi+1]-occ[bi]-1; while(maxdone < k && tsize >= c[maxdone]){ tsize -= c[maxdone]; tsize -= 1; maxdone++; } bi++; continue; } bool w = false, b = false; if(maxdone >= back_cram[bi]){ w = true; if(occ[bi+1]-occ[bi] - 1 >= mint.query(0, k, 0, back_cram[bi]-1, maxdone+1)) b = true; } else{ int l = maxdone; int r = back_cram[bi] + 1; while(l+1<r){ int m = l + (r-l)/2; int prened = sum.query(0, k, 0, maxdone, m) + (m-maxdone-1); int preav = solver-occ[bi]-1; if(prened > preav) r = m; else l = m; } int prened = max(0,sum.query(0, k, 0, maxdone, l) + (l-maxdone-1)); int qans = sum.query(0, k, 0, l, back_cram[bi]); int postned = max(0,sum.query(0, k, 0, l, back_cram[bi]) + (back_cram[bi]-l-1)); int preav = solver-occ[bi]-1; int postav = occ[bi+1]-solver-1; if(prened <= preav && postned <= postav){ w = true; } if(prened + postned + 1 < occ[bi+1]-occ[bi]-1 || occ[bi]+prened + 1 < solver || prened == 0 || postned == 0) b = true; } if(w && b) s[solver] = '?'; else if(w) s[solver] = '_'; else if(b) s[solver] = 'X'; else assert(false); } return s; } /* #include "paint.h" #include <vector> #include <string> #include <cstdio> #include <cassert> const int S_MAX_LEN = 200 * 1000; char buf[S_MAX_LEN + 1]; int main() { assert(1 == scanf("%s", buf)); std::string s = buf; int c_len; assert(1 == scanf("%d", &c_len)); std::vector<int> c(c_len); for (int i = 0; i < c_len; i++) { assert(1 == scanf("%d", &c[i])); } std::string ans = solve_puzzle(s, c); printf("%s\n", ans.data()); return 0; } */

Compilation message (stderr)

paint.cpp: In function 'std::string solve_puzzle(std::string, std::vector<int>)':
paint.cpp:92:17: warning: unused variable 'qans' [-Wunused-variable]
   92 |             int qans = sum.query(0, k, 0, l, back_cram[bi]);
      |                 ^~~~
#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...