結果
| 問題 |
No.1405 ジグザグロボット
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2025-03-27 00:03:03 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 17 ms / 3,153 ms |
| コード長 | 6,400 bytes |
| コンパイル時間 | 3,179 ms |
| コンパイル使用メモリ | 218,840 KB |
| 実行使用メモリ | 39,956 KB |
| 最終ジャッジ日時 | 2025-03-27 00:03:13 |
| 合計ジャッジ時間 | 8,701 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 35 |
ソースコード
#include <bits/stdc++.h>
#define rep(i, j, k) for (int i = (j); i <= (k); ++i)
#define per(i, j, k) for (int i = (j); i >= (k); --i)
#define SZ(v) int((v).size())
#define ALL(v) (v).begin(),(v).end()
#define fi first
#define se second
using ll = long long;
using pii = std::pair<int, int>;
using pll = std::pair<ll, ll>;
template<class T> void chkmn(T &x, T y) { if (y < x) x = y; }
template<class T> void chkmx(T &x, T y) { if (y > x) x = y; }
using namespace std;
const int maxn = 300010;
struct segtree {
int t[maxn << 2], lz[maxn << 2];
#define mid ((l + r) >> 1)
void build(int c, int l, int r) {
lz[c] = 0;
if (l == r) return t[c] = 0, void();
build(c << 1, l, mid), build(c << 1 | 1, mid + 1, r);
t[c] = min(t[c << 1], t[c << 1 | 1]);
}
void down(int c) {
if (!lz[c]) return;
t[c << 1] += lz[c], lz[c << 1] += lz[c];
t[c << 1 | 1] += lz[c], lz[c << 1 | 1] += lz[c];
lz[c] = 0;
}
void upd(int c, int l, int r, int x, int y, int v) {
if (l == x && r == y) return t[c] += v, lz[c] += v, void();
down(c);
if (y <= mid) upd(c << 1, l, mid, x, y, v);
else if (x > mid) upd(c << 1 | 1, mid + 1, r, x, y, v);
else upd(c << 1, l, mid, x, mid, v), upd(c << 1 | 1, mid + 1, r, mid + 1, y, v);
t[c] = min(t[c << 1], t[c << 1 | 1]);
}
int find(int c, int l, int r) {
if (t[c]) return -1;
if (l == r) return l;
int res = find(c << 1, l, mid);
if (res != -1) return res;
return find(c << 1 | 1, mid + 1, r);
}
#undef mid
} seg;
int n, X, Y, tot, pos[maxn], L[maxn], R[maxn], from[maxn], vis[maxn], delta[maxn], gx[maxn];
pll t[maxn << 2];
ll lz[maxn << 2], f[maxn], g[maxn];
string str, s[maxn];
vector<pii> ans, vec[maxn];
#define mid ((l + r) >> 1)
void build(int c, int l, int r) {
lz[c] = 0;
if (l == r) return t[c] = pll(-1e18, l - 1), void();
build(c << 1, l, mid), build(c << 1 | 1, mid + 1, r);
t[c] = max(t[c << 1], t[c << 1 | 1]);
}
void down(int c) {
if (!lz[c]) return;
t[c << 1].fi += lz[c], lz[c << 1] += lz[c];
t[c << 1 | 1].fi += lz[c], lz[c << 1 | 1] += lz[c];
lz[c] = 0;
}
void cg(int c, int l, int r, int x, ll v) {
if (l == r) return t[c] = pll(v, l - 1), void();
down(c);
if (x <= mid) cg(c << 1, l, mid, x, v);
else cg(c << 1 | 1, mid + 1, r, x, v);
t[c] = max(t[c << 1], t[c << 1 | 1]);
}
void upd(int c, int l, int r, int x, int y, ll v) {
if (l == x && r == y) return t[c].fi += v, lz[c] += v, void();
down(c);
if (y <= mid) upd(c << 1, l, mid, x, y, v);
else if (x > mid) upd(c << 1 | 1, mid + 1, r, x, y, v);
else upd(c << 1, l, mid, x, mid, v), upd(c << 1 | 1, mid + 1, r, mid + 1, y, v);
t[c] = max(t[c << 1], t[c << 1 | 1]);
}
pll qry(int c, int l, int r, int x, int y) {
if (l == x && r == y) return t[c];
down(c);
if (y <= mid) return qry(c << 1, l, mid, x, y);
else if (x > mid) return qry(c << 1 | 1, mid + 1, r, x, y);
else return max(qry(c << 1, l, mid, x, mid), qry(c << 1 | 1, mid + 1, r, mid + 1, y));
}
#undef mid
pll calc(ll mid) {
build(1, 1, tot), f[0] = g[0] = 0;
rep (i, 1, tot) {
cg(1, 1, tot, i, f[i - 1]);
for (auto s : vec[i]) upd(1, 1, tot, 1, s.fi, s.se);
auto s = qry(1, 1, tot, 1, i);
from[i] = s.se, f[i] = s.fi - mid, g[i] = g[s.se] + 1;
}
return pll(f[tot], g[tot]);
}
int main() {
cin.tie(nullptr) -> ios::sync_with_stdio(false);
cin >> n >> X >> Y >> str, tot = 1;
for (char c : str) {
if (c == 'S') tot++;
else s[tot] += c;
}
if (tot <= Y) return cout << "-1\n", 0;
seg.build(1, 1, tot);
rep (i, 1, tot) {
for (char c : s[i]) {
if (c == 'L') {
int lim = seg.find(1, 1, tot);
if (lim == -1) lim = i + 1;
if (lim > 1) {
vec[i].emplace_back(lim - 1, -1);
seg.upd(1, 1, tot, 1, lim - 1, -1);
}
} else {
vec[i].emplace_back(i, 1);
seg.upd(1, 1, tot, 1, i, 1);
}
}
}
int l = 0, r = n, slope = 0;
while (l <= r) {
int mid = (l + r) >> 1;
auto res = calc(mid);
if (res.se >= Y + 1) slope = mid, l = mid + 1;
else r = mid - 1;;
}
auto xres = calc(slope), yres = calc(slope + 1);
ll DP;
if (xres.se == Y + 1) {
DP = xres.fi + 1ll * slope * xres.se;
} else {
ll xl = xres.se, yl = xres.fi + 1ll * slope * xres.se;
ll xr = yres.se, yr = yres.fi + 1ll * (slope + 1) * yres.se;
DP = yl + (yr - yl) * (Y + 1 - xl) / (xr - xl);
}
if (DP < X) return cout << "-1\n", 0;
vector<int> dpos, cpos;
int cur = tot;
while (cur) cur = from[cur], dpos.emplace_back(cur + 1);
for (int x : dpos) vis[x] = 1;
calc(slope);
cur = tot;
while (cur) cur = from[cur], cpos.emplace_back(cur + 1);
for (int x : cpos) if (!vis[x] && SZ(dpos) < Y + 1) dpos.emplace_back(x);
sort(ALL(dpos));
rep (i, 0, Y) pos[i] = dpos[i];
pos[Y + 1] = tot + 1, cur = 0;
rep (i, 0, Y) {
int mn = cur, mx = cur, pre = cur;
rep (j, pos[i], pos[i + 1] - 1) {
for (char c : s[j]) {
if (c == 'L') cur--;
else cur++;
chkmx(cur, pre), chkmn(mn, cur), chkmx(mx, cur);
}
}
L[i] = mn, R[i] = mx;
}
int rest = DP - X;
per (i, Y, 0) if (rest) {
int cur = L[i];
rep (j, pos[i], pos[i + 1] - 1) {
for (char c : s[j]) {
if (c == 'L') cur--;
else cur++;
chkmx(cur, L[i]), chkmn(cur, R[i]);
}
}
int l = 1, r = R[i] - L[i], res = 0;
while (l <= r) {
int mid = (l + r) >> 1, tmp = L[i];
rep (j, pos[i], pos[i + 1] - 1) {
for (char c : s[j]) {
if (c == 'L') tmp--;
else tmp++;
chkmx(tmp, L[i]), chkmn(tmp, R[i] - mid);
}
}
if (cur - tmp <= rest) res = mid, l = mid + 1;
else r = mid - 1;
}
R[i] -= res;
int tmp = L[i];
rep (j, pos[i], pos[i + 1] - 1) {
for (char c : s[j]) {
if (c == 'L') tmp--;
else tmp++;
chkmx(tmp, L[i]), chkmn(tmp, R[i]);
}
}
gx[i] = cur - tmp, rest -= cur - tmp;
}
int psum = 0;
rep (i, 0, Y) L[i] -= psum, R[i] -= psum, psum += gx[i];
rep (i, 0, Y) {
ans.emplace_back(L[i] - 1, i), ans.emplace_back(R[i] + 1, i);
rep (j, L[i], R[i]) if (i == Y || j < L[i + 1] || j > R[i + 1]) ans.emplace_back(j, i + 1);
}
sort(ALL(ans)), ans.erase(unique(ALL(ans)), ans.end());
cout << SZ(ans) << '\n';
for (auto s : ans) cout << s.fi << ' ' << s.se << '\n';
}