이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vi = vector<int>;
using pi = pair<int,int>;
#define all(v) v.begin(),v.end()
#define sort(v) sort(all(v))
#define endl '\n'
#define forn(i,n) for(int i = 0; i < n; ++i)
#define forbe(i,b,e) for(int i = b; i < e; ++i)
#define forr(i,n) for(int i = n-1; i >= 0; --i)
#define sz(v) ((int)v.size())
#define pb push_back
#define f first
#define s second
struct aib{
vi f;
int n;
aib(int _n) {
n = _n;
f.assign(n,0);
}
void add(int x, int v) {
for(;x <n; x |= (x+1))
f[x] += v;
}
int q(int x) {
int r = 0;
for(;x >= 0; x = (x&(x+1))-1)
r += f[x];
return r;
}
int query(int l, int r) {
return q(r) - q(l-1);
}
};
struct psum{
vi f;
vi _v;
int n;
psum(int _n) {
n = _n;
f.assign(n,0);
_v.assign(n,0);
}
void add(int x, int v) {
_v[x] += v;
}
void gen() {
forn(i,n) {
if (i) f[i] = f[i-1];
f[i] += _v[i];
}
}
int q(int x) {
if (x < 0)
return 0;
assert(f[x] > -1);
return f[x];
}
int query(int l, int r) {
if (r < l)
return 0;
assert(q(r) - q(l-1) > -1);
return q(r) - q(l-1);
}
};
string solve_puzzle(string s, vi c) {
int n = sz(s);
int k = sz(c);
string ans = s;
vi type(n,0);
vi pnt(k,0);
psum tr(n);
psum trx(n);
psum posseg(n+5);
psum minseg(n+5);
forn(i,n)
if (s[i] == '_')
tr.add(i,1);
forn(i,n)
if (s[i] == 'X')
trx.add(i,1);
tr.gen();
trx.gen();
vector<int> pdp[k];
vector<int> sdp[k];
forn(j,k) pdp[j].assign(n,-1);
forn(j,k) sdp[j].assign(n,-1);
forn(j,k) {
int lst = 1;
if (!j) {
forn(i,n - c[j]+1) {
if (i+c[j]-1) pdp[j][i+c[j]-1] = pdp[j][i+c[j]-2];
if (pdp[j][i+c[j]-1] != -1 && (!trx.query(i+c[j]-1,i+c[j]-1) && lst))
continue;
lst = 0;
if (tr.query(i,i+c[j]-1) > 0) continue;
if (trx.query(0,i-1) > 0) continue;
lst = 1;
pdp[j][i+c[j]-1] = i+c[j]-1;
}
} else {
forbe(i,1,n - c[j]+1) {
if (i+c[j]-1) pdp[j][i+c[j]-1] = pdp[j][i+c[j]-2];
if (pdp[j][i+c[j]-1] != -1 && (!trx.query(i+c[j]-1,i+c[j]-1) && lst))
continue;
lst = 0;
if (tr.query(i,i+c[j]-1) > 0) continue;
if (pdp[j-1][i-1] == i-1 || pdp[j-1][i-1] == -1) continue;
if (trx.query(pdp[j-1][i-1]+1,i-1)) continue;
lst = 1;
pdp[j][i+c[j]-1] = i+c[j]-1;
}
}
}
forr(j,k) {
int lst = 1;
if (j == k-1) {
forr(i,n-c[j]+1) {
if (i < n-1) sdp[j][i] = sdp[j][i+1];
if (sdp[j][i] != -1 && (!trx.query(i,i) && lst))
continue;
lst = 0;
if (tr.query(i,i+c[j]-1) > 0) continue;
if (trx.query(i+c[j],n-1) > 0) continue;
lst = 1;
sdp[j][i] = i;
}
} else {
forr(i,n-c[j]) {
if (i < n-1) sdp[j][i] = sdp[j][i+1];
if (sdp[j][i] != -1 && (!trx.query(i,i) && lst))
continue;
lst = 0;
if (tr.query(i,i+c[j]-1) > 0) continue;
if (sdp[j+1][i+c[j]] == i+c[j] || sdp[j+1][i+c[j]] == -1) continue;
if (trx.query(i+c[j],sdp[j+1][i+c[j]]-1)) continue;
lst = 1;
sdp[j][i] = i;
}
}
}
#ifdef ONPC
forn(j,k) {
forn(i,n) {
if (pdp[j][i] == -1)
cout << 0;
else
cout << pdp[j][i];
/* cout << 1; */
}
cout << endl;
}
forn(j,k) {
forn(i,n) {
if (sdp[j][i] == -1)
cout << 0;
else
cout << sdp[j][i];
}
cout << endl;
}
#endif
int il, ir;
forn(j,k) {
forn(i,n) {
if (i + c[j] > n) break;
/* cout << j << ' ' << i << ' ' << il << ' ' << ir << endl; */
if (j) {
if (!i) continue;
il = pdp[j-1][i-1];
if (il == -1 || il == i-1)
continue;
} else {
il = -1;
}
if (j == k-1) {
ir = n;
} else {
if (i + c[j] == n) continue;
ir = sdp[j+1][i+c[j]];
if (ir == -1 || ir == i + c[j])
continue;
}
/* cout << j << ' ' << i << endl; */
if (tr.query(i,i+c[j]-1) > 0) continue;
if (trx.query(il+1, i-1)) continue;
if (trx.query(i + c[j], ir-1)) continue;
/* cout << j << ' ' << i << endl; */
if (j) minseg.add(pdp[j-1][i-1]+1,1);
else minseg.add(0,1);
minseg.add(i,-1);
minseg.add(i+c[j],1);
if (j!=k-1) minseg.add(sdp[j+1][i+c[j]],-1);
posseg.add(i,1);
posseg.add(i+c[j],-1);
}
}
/* forn(j,k) { */
/* minseg.add(pnt[j]+c[j],1); */
/* if (j < k-1) */
/* minseg.add(pnt[j+1],-1); */
/* else */
/* minseg.add(n,-1); */
/* } */
/* */
/* int lm; */
/* int lp = n+1; */
/* forr(j,k) { */
/* lm = lp; */
/* lp = pnt[j]; */
/* forbe(i,pnt[j], lm - c[j]) { */
/* if (tr.query(i,i+c[j]-1) > 0) */
/* continue; */
/* lp = i; */
/* posseg.add(i,1); */
/* posseg.add(i+c[j],-1); */
/* } */
/* */
/* minseg.add(pnt[j],1); */
/* minseg.add(lp,-1); */
/* } */
posseg.gen();
minseg.gen();
forn(i,n) {
if (posseg.q(i) > 0) {
if (minseg.q(i) > 0)
ans[i] = '?';
else
ans[i] = 'X';
}
else
ans[i] = '_';
}
return ans;
}
#ifdef ONPC
void solve() {
int n, k;
cin >> k;
string s;
cin >> s;
vi c(k);
forn(i,k)
cin >> c[i];
string ans = solve_puzzle(s,c);
cout << ans << endl;
}
int main() {
freopen("in", "r", stdin);
// ios_base::sync_with_stdio(0);cin.tie(0);
solve();
}
#endif
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |