[ABC285F] Substring of Sorted String
考虑什么样的区间可能满足要求。
满足要求的区间即一个是
所以我们可以发现第一个要求是:区间
但是区间就算升序排序,也不一定满足要求。比如
于是可以发现,当区间升序排序,设
线段树维护即可。
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5, INF = 2e9, MOD = 1e9 + 7;
inline int read()
{
int op = 1, x = 0;
char ch = getchar();
while ((ch < '0' || ch > '9') && ch != '-') ch = getchar();
while (ch == '-')
{
op = -op;
ch = getchar();
}
while (ch >= '0' and ch <= '9')
{
x = (x << 1) + (x << 3) + (ch ^ 48);
ch = getchar();
}
return x * op;
}
inline void write(int x)
{
if (x < 0) putchar('-'), x = -x;
if (x > 9) write(x / 10);
putchar(x % 10 + '0');
}
int n, q;
string s;
int a[N];
bool a1[N], a2[N];
class SegmentTree
{
public:
struct Node
{
int l, r, ll, rr;
bool is_as;
friend Node operator+(const Node& x, const Node& y)
{
Node c;
c.ll = x.ll;
c.rr = y.rr;
c.is_as = x.is_as && y.is_as && (x.rr <= y.ll);
return c;
}
}tr[N << 2];
void pushup(int u)
{
tr[u].ll = tr[u << 1].ll;
tr[u].rr = tr[u << 1 | 1].rr;
tr[u].is_as = tr[u << 1].is_as && tr[u << 1 | 1].is_as && (tr[u << 1].rr <= tr[u << 1 | 1].ll);
}
void build(int u, int l, int r)
{
tr[u] = { l, r, a[l], a[l], 1 };
if (l == r) return;
int mid = l + r >> 1;
build(u << 1, l, mid);
build(u << 1 | 1, mid + 1, r);
pushup(u);
}
void update(int u, int x, int v)
{
if (tr[u].l == tr[u].r)
{
tr[u].ll = tr[u].rr = v;
return;
}
int mid = tr[u].l + tr[u].r >> 1;
if (x <= mid) update(u << 1, x, v);
else update(u << 1 | 1, x, v);
pushup(u);
}
Node query(int u, int l, int r)
{
if (tr[u].l >= l and tr[u].r <= r) return tr[u];
int mid = tr[u].l + tr[u].r >> 1;
Node ans;
ans.ll = -1;
if (l <= mid) ans = query(u << 1, l, r);
if (r > mid)
{
if (ans.ll == -1) ans = query(u << 1 | 1, l, r);
else ans = ans + query(u << 1 | 1, l, r);
}
return ans;
}
}t;
class Bit
{
public:
long long tr[N];
void add(int x, int v)
{
while (x < N)
{
tr[x] += 1LL * v;
x += x & -x;
}
}
long long query(int x)
{
long long ans = 0;
while (x)
{
ans += tr[x];
x -= x & -x;
}
return ans;
}
}t2;
int cnt;
int main()
{
// freopen("*.in", "r", stdin);
// freopen("*.out", "w", stdout);
//ios::sync_with_stdio(0), cin.tie(nullptr), cout.tie(nullptr);
cin >> n >> s >> q;
for (int i = 1; i <= n; i++)
{
a[i] = s[i - 1];
t2.add(a[i], 1);
}
t.build(1, 1, n);
for (int i = 1; i <= q; i++)
{
int op;
cin >> op;
if (op == 1)
{
int x;
char c;
cin >> x >> c;
t.update(1, x, c);
t2.add(a[x], -1);
a[x] = c;
t2.add(a[x], 1);
}
else
{
int l, r;
cin >> l >> r;
cnt++;
a1[cnt] = t.query(1, l, r).is_as;
if (!a1[cnt])
{
cout << "No\n";
continue;
}
int ll = a[l] + 1;
int rr = a[r] - 1;
if (ll > rr) a2[cnt] = 1;
else
{
int cnts = t2.query(rr) - t2.query(ll - 1);
int lll = upper_bound(a + l, a + r + 1, a[l]) - a;
int rrr = lower_bound(a + l, a + r + 1, a[r]) - 1 - a;
if (cnts > rrr - lll + 1) a2[cnt] = 0;
else a2[cnt] = 1;
}
if (a2[cnt] && a1[cnt]) cout << "Yes\n";
else cout << "No\n";
}
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」