题意:
给定一个字符串,1 x,c是将s[x]修改为c。2 l r 则是询问t为字符串升序排列之后的串,问原串中l到r的串是否为t的子串。
思路:
满足2的条件为l到r本身升序排列,且其他位置没有能插入到l至r的。
/*keep on going and never give up*/
#include<cstdio>
#include<iostream>
#include<queue>
#include<algorithm>
using namespace std;
typedef pair<int, int> pii;
#define int long long
#define lowbit(x) x&(-x)
#define endl '\n'
#define wk is zqx ta die
int c[30][100005];
int n;
void add(int id, int x, int y) {
while (x <= n) {
c[id][x] += y;
x += lowbit(x);
}
}
int query(int id, int r) {
int sum = 0;
while (r > 0) {
sum += c[id][r];
r -= lowbit(r);
}
return sum;
}
signed main() {
std::ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> n;
string s;
cin >> s;
s = '!' + s;
for (int i = 1; i <= n; i++) {
add(s[i] - 'a' + 1, i, 1);
if (i > 1 && s[i] < s[i - 1]) {
add(27, i, 1);
}
}
int q;
cin >> q;
while (q--) {
int m;
cin >> m;
if (m == 1) {
int x;
char c;
cin >> x >> c;
add(s[x] - 'a' + 1, x, -1);
if (x > 1 && s[x] < s[x - 1]) {
add(27, x, -1);
}
if (x < n && s[x] > s[x + 1]) {
add(27, x + 1, -1);
}
s[x] = c;
add(s[x] - 'a' + 1, x, 1);
if (x > 1 && s[x] < s[x - 1]) {
add(27, x, 1);
}
if (x < n && s[x] > s[x + 1]) {
add(27, x + 1, 1);
}
} else {
int l, r;
cin >> l >> r;
int sum = query(27, r) - query(27, l);
if (sum != 0) {
cout << "No" << endl;
continue;
} else {
bool ok = 0;
for (int i = s[l] - 'a' + 2; i <= s[r] - 'a'; i++) {
if (query(i, n) != query(i, r - 1) - query(i, l)) {
ok = 1;
break;
}
}
if (ok == 1) {
cout << "No" << endl;
} else {
cout << "Yes" << endl;
}
}
}
}
return 0;
}