专栏文章
在银河中孤独摇摆
P14060题解参与者 11已保存评论 16
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 16 条
- 当前快照
- 1 份
- 快照标识符
- @mintmt3u
- 此快照首次捕获于
- 2025/12/02 08:09 3 个月前
- 此快照最后确认于
- 2025/12/02 08:09 3 个月前
钦定首字符为 。操作过程可以看成,对于每一个 ,选择前面的一个 配对上,(当然可能选择不到),然后同时把他们删除。如果每一个 都能成功配对,意味着开头始终不会变成 ,这个串自然是合法的。
考虑把 看成 ,把 看成 ,则串合法的充要条件是任意前缀和非负,即对于 ,。
这样枚举每一个子串直接 check,有 和 的做法。
令原串的前缀和为 。考虑固定左端点 , 合法即 ,。考虑单调栈,对于每一个 ,求出最小的 使得 ,则 的 都是合法右端点。
这样有时间复杂度 的做法。
CPP#include <bits/stdc++.h>
#define F(i, a, b) for (int i = (a); i <= (b); ++i)
#define dF(i, a, b) for (int i = (a); i >= (b); --i)
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;
typedef vector<int> vec;
typedef array<int, 2> arr;
const int N = 1e7 + 5;
int n, a[N], s[N], r[N], st[N], tp; char c[N]; LL ans;
void Solve() {
F(i, 1, n + 1) {
while (tp > 0 && s[st[tp]] < s[i])
r[st[tp--]] = i;
st[++tp] = i;
}
while (tp) r[st[tp--]] = n + 2;
F(i, 1, n) ans += r[i] - i - 1;
}
void mian() {
cin >> c, n = strlen(c), ans = 0;
F(i, 1, n) a[i] = c[i - 1] - '0';
s[n + 1] = 0;
dF(i, n, 1) s[i] = s[i + 1] + (a[i] ? 1 : -1);
Solve();
dF(i, n, 1) s[i] = s[i + 1] + (a[i] ? -1 : 1);
Solve();
cout << ans << "\n";
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
int _; cin >> _; while (_--) mian();
return 0;
}
相关推荐
评论
共 16 条评论,欢迎与作者交流。
正在加载评论...