1989. Subpalindromes
Time limit: 0.5 second
Memory limit: 64 MB
You have a string and queries of two types:
- replace i’th character of the string by character a;
- check if substring sj...sk is a palindrome.
Input
The first line contains a string consisting of
n small English letters. The second line contains an integer
mthat is the number of queries (5 ≤
n,
m ≤ 10
5). The next
m lines contain the queries.
Each query has either form “change i a”, or “palindrome? j k”, where
i,
j,
k are integers (1 ≤
i ≤
n; 1 ≤
j ≤
k ≤
n), and character
a is a small English letter.
Output
To all second type queries, you should output “Yes” on a single line if substring
s
j...
s
k is a palindrome and “No” otherwise.
Sample
input output abcda
5
palindrome? 1 5
palindrome? 1 1
change 4 b
palindrome? 1 5
palindrome? 2 4
No
Yes
Yes
Yes
Problem Author: Mikhail Rubinchik
Problem Source: Open Ural FU Championship 2013
Tags:
palindromes
)
Difficulty: 310
Printable version
Submit solution
Discussion (5)
All submissions (5091)
All accepted submissions (1022)
Solutions rating (432)
1989. Subpalindromes
Time limit: 0.5 second
Memory limit: 64 MB
Memory limit: 64 MB
You have a string and queries of two types:
- replace i’th character of the string by character a;
- check if substring sj...sk is a palindrome.
Input
The first line contains a string consisting of
n small English letters. The second line contains an integer
mthat is the number of queries (5 ≤
n,
m ≤ 10
5). The next
m lines contain the queries.
Each query has either form “change i a”, or “palindrome? j k”, where i, j, k are integers (1 ≤ i ≤ n; 1 ≤ j ≤ k ≤ n), and character a is a small English letter.
Each query has either form “change i a”, or “palindrome? j k”, where i, j, k are integers (1 ≤ i ≤ n; 1 ≤ j ≤ k ≤ n), and character a is a small English letter.
Output
To all second type queries, you should output “Yes” on a single line if substring
s
j...
s
k is a palindrome and “No” otherwise.
Sample
input | output |
---|---|
abcda 5 palindrome? 1 5 palindrome? 1 1 change 4 b palindrome? 1 5 palindrome? 2 4 | No Yes Yes Yes |
Problem Author: Mikhail Rubinchik
Problem Source: Open Ural FU Championship 2013
Problem Source: Open Ural FU Championship 2013
Tags:
palindromes
)
Difficulty: 310
Printable version
Submit solution
Discussion (5)
All submissions (5091) All accepted submissions (1022) Solutions rating (432)
All submissions (5091) All accepted submissions (1022) Solutions rating (432)
思路:
比较询问区间正向hash 值和反向hash值,相等则说明是回文字符串。
对于求区间的hash值,因为时限只有500ms,所以至少要在logn的复杂度求出hash值,对此线段树和数组数组都可以
线段树版:
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <cstdlib>
#include <set>
#include <map>
#include <cctype>
#include <list>
#include <cmath>
#include <bitset>
#include <queue>
#include <stack>
#include <sstream>
#include <functional>
#include <cassert>
using namespace std;
#define tmax(a, b) if (b > a) a = b
#define tmin(a, b) if (b < a) a = b
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
#define par(a) a >> 1
char inc() { char _[10]; scanf("%s", _); return _[0]; }
int ini() { int _; scanf("%d", &_); return _; }
long long inll() { long long _; scanf("%I64d", &_); return _; }
double ind() { double _; scanf("%lf", &_); return _; }
string ins() { string _; cin >> _; return _; }
int inl(char _[]) { if (!fgets(_, (int)1e8, stdin)) return -1; int i = strlen(_); if (_[i - 1] == '\n') _[--i] = 0; return i; }
typedef pair<int, int> pii;
typedef pair<char, char> pcc;
typedef long long LL;
typedef unsigned long long ULL;
const int inf = 0x3f3f3f3f;
const LL lnf = 0x3f3f3f3f3f3f3f3f;
const double pi = 3.14159265358979323846;
const double eps = 1e-8;
const int mod = 100007;
const int maxn = 1e5 + 10;
char str[maxn];
int len;
ULL d[maxn];
ULL sum[2][maxn << 2];
void PushUp(int rt, int flag) {
sum[flag][rt] = sum[flag][rt << 1] + sum[flag][rt << 1 | 1];
}
void Build(int l, int r, int rt, int flag) {
if (l == r) {
sum[flag][rt] = d[l] * (str[l] - 'a');
return;
}
int m = (l + r) >> 1;
Build(lson, flag);
Build(rson, flag);
PushUp(rt, flag);
}
void Update(int p, ULL v, int l, int r, int rt, int flag) {
if (l == r) {
sum[flag][rt] = v;
return;
}
int m = (l + r) >> 1;
if (p <= m) Update(p, v, lson, flag);
else Update(p, v, rson, flag);
PushUp(rt, flag);
}
ULL Query(int L, int R, int l, int r, int rt, int flag) {
if (L <= l && r <= R) {
return sum[flag][rt];
}
int m = (l + r) >> 1;
ULL res = 0;
if (L <= m) res += Query(L, R, lson, flag);
if (m < R) res += Query(L, R, rson, flag);
return res;
}
int main() {
int CAS = 0;
//std::ios::sync_with_stdio(0);
//std::cin.tie(0);
#ifdef NIGHT_13
//freopen("myout.txt", "w", stdout);
freopen("in.txt", "r", stdin);
int time_night_13 = clock();
#endif // NIGHT_13
scanf("%s", str + 1);
len = strlen(str + 1);
d[1] = 1;
for (int i = 2; i <= len; ++i) d[i] = d[i - 1] * 29;
Build(1, len, 1, 0);
reverse(str + 1, str + 1 + len);
Build(1, len, 1, 1);
int T = ini();
while (T--) {
char op[100];
scanf("%s", op);
if (op[0] == 'p') {
int l, r;
scanf("%d%d", &l, &r);
ULL ls = Query(l, r, 1, len, 1, 0);
ULL rs = Query(len + 1 - r, len + 1 - l, 1, len, 1, 1);
int k1 = l - 1, k2 = len - r;
if (k1 < k2) ls *= d[k2 - k1 + 1];
if (k1 > k2) rs *= d[k1 - k2 + 1];
puts(ls == rs ? "Yes" : "No");
} else {
int a;
scanf("%d%s", &a, op);
Update(a, d[a] * (op[0] - 'a'), 1, len, 1, 0);
Update(len + 1 - a, d[len + 1 - a] * (op[0] - 'a'), 1, len, 1, 1);
}
}
#ifdef NIGHT_13
fprintf(stderr, "\nTime: %dms\n", (int)clock() - time_night_13);
#endif // NIGHT_13
return 0;
}
树状数组版:
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <cstdlib>
#include <set>
#include <map>
#include <cctype>
#include <list>
#include <cmath>
#include <bitset>
#include <queue>
#include <stack>
#include <sstream>
#include <functional>
#include <cassert>
using namespace std;
#define tmax(a, b) if (b > a) a = b
#define tmin(a, b) if (b < a) a = b
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
#define par(a) a >> 1
char inc() { char _[10]; scanf("%s", _); return _[0]; }
int ini() { int _; scanf("%d", &_); return _; }
long long inll() { long long _; scanf("%I64d", &_); return _; }
double ind() { double _; scanf("%lf", &_); return _; }
string ins() { string _; cin >> _; return _; }
int inl(char _[]) { if (!fgets(_, (int)1e8, stdin)) return -1; int i = strlen(_); if (_[i - 1] == '\n') _[--i] = 0; return i; }
typedef pair<int, int> pii;
typedef pair<char, char> pcc;
typedef long long LL;
typedef unsigned long long ULL;
const int inf = 0x3f3f3f3f;
const LL lnf = 0x3f3f3f3f3f3f3f3f;
const double pi = 3.14159265358979323846;
const double eps = 1e-8;
const int mod = 100007;
const int maxn = 1e5 + 10;
char str[maxn];
int len;
ULL d[maxn] = {0, 1};
ULL bt[maxn][2];
void Add(int x, int k, ULL v) {
while (x <= len) {
bt[x][k] += v;
x += -x & x;
}
}
ULL Query(int x, int k) {
ULL res = 0;
while (x) {
res += bt[x][k];
x -= -x & x;
}
return res;
}
int main() {
int CAS = 0;
//std::ios::sync_with_stdio(0);
//std::cin.tie(0);
#ifdef NIGHT_13
//freopen("myout.txt", "w", stdout);
freopen("in.txt", "r", stdin);
int time_night_13 = clock();
#endif // NIGHT_13
scanf("%s", str + 1);
len = strlen(str + 1);
for (int i = 2; i <= len; ++i) d[i] = d[i - 1] * 29;
for (int i = 1; i <= len; ++i) {
Add(i, 0, d[i] * str[i]);
Add(len + 1 - i, 1, d[len + 1 - i] * str[i]);
}
int T = ini();
while (T--) {
char op[100];
scanf("%s", op);
if (op[0] == 'p') {
int l, r;
scanf("%d%d", &l, &r);
ULL ls = Query(r, 0) - Query(l - 1, 0);
ULL rs = Query(len + 1 - l, 1) - Query(len - r, 1);
int k1 = l - 1, k2 = len - r;
if (k1 < k2) ls *= d[k2 - k1 + 1];
if (k1 > k2) rs *= d[k1 - k2 + 1];
puts(ls == rs ? "Yes" : "No");
} else {
int a;
scanf("%d%s", &a, op);
Add(a, 0, d[a] * (op[0] - str[a]));
Add(len + 1 - a, 1, d[len + 1 - a] * (op[0] - str[a]));
str[a] = op[0];
}
}
#ifdef NIGHT_13
fprintf(stderr, "\nTime: %dms\n", (int)clock() - time_night_13);
#endif // NIGHT_13
return 0;
}