-
Notifications
You must be signed in to change notification settings - Fork 166
/
Palindrome Queries.cpp
92 lines (82 loc) · 2.29 KB
/
Palindrome Queries.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll MOD = 1e9+7;
const ll p[2] = {31, 37};
const int maxN = 2e5+5;
char S[maxN];
int N, K;
ll pows[2][maxN], invs[2][maxN], F[2], B[2], ds[2][2][maxN];
ll inverse(ll x){
ll res = 1;
ll b = MOD-2;
while(b){
if(b&1) res = (res * x) % MOD;
x = (x * x) % MOD;
b >>= 1;
}
return res;
}
void update(int pt, int t, int idx, ll val){
val %= MOD; val += MOD; val %= MOD;
for(int i = idx+1; i < maxN; i += -i&i)
ds[pt][t][i] = (ds[pt][t][i] + val) % MOD;
}
ll query(int pt, int t, int idx){
if(idx < 0) return 0;
ll sum = 0;
for(int i = idx+1; i > 0; i -= -i&i)
sum = (sum + ds[pt][t][i]) % MOD;
return sum;
}
void init(){
for(int t = 0; t < 2; t++){
pows[t][0] = invs[t][0] = 1;
for(int i = 1; i < maxN; i++){
pows[t][i] = (pows[t][i-1] * p[t]) % MOD;
invs[t][i] = inverse(pows[t][i]);
}
update(t, 0, 0, (int) (S[0]-'a'+1) * pows[t][N-1]);
update(t, 1, 0, (int) (S[0]-'a'+1));
for(int i = 1; i < N; i++){
int c = (int) (S[i]-'a'+1);
update(t, 0, i, c * pows[t][N-i-1]);
update(t, 1, i, c * pows[t][i]);
}
}
}
void modify(int a, char c){
int newchar = (int) (c - 'a' + 1);
int oldchar = (int) (S[a] - 'a' + 1);
for(int t = 0; t < 2; t++){
update(t, 0, a, -oldchar * pows[t][N-a-1]);
update(t, 0, a, newchar * pows[t][N-a-1]);
update(t, 1, a, -oldchar * pows[t][a]);
update(t, 1, a, newchar * pows[t][a]);
}
S[a] = c;
}
bool palindrome(int a, int b){
for(int t = 0; t < 2; t++){
F[t] = (query(t, 0, b) - query(t, 0, a-1) + MOD) % MOD;
F[t] = (F[t] * invs[t][N-b-1]) % MOD;
B[t] = (query(t, 1, b) - query(t, 1, a-1) + MOD) % MOD;
B[t] = (B[t] * invs[t][a]) % MOD;
}
return F[0] == B[0] && F[1] == B[1];
}
int main(){
scanf("%d %d %s", &N, &K, S);
init();
for(int i = 0, t, a, b; i < K; i++){
char c;
scanf("%d", &t);
if(t == 1){
scanf("%d %c", &a, &c);
modify(a-1, c);
} else if(t == 2){
scanf("%d %d", &a, &b);
printf("%s\n", palindrome(a-1, b-1) ? "YES" : "NO");
}
}
}