Subpalindromes
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 m that 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”, wherei, 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.
Example
input | output |
---|---|
| |
题意:给一个字符串,n次操作,每次操作是 查询 区间[l,r] 的字符串是否是回文,或 改变一个位置的字符。
思路:利用树状数组维护 正反字符串的哈希值,每一次都判断查询区间的 正反是的哈希值是否相等——以此判断是否回文
AC代码:
#include<bits/stdc++.h>
#define debug(x) cout << "[" << #x <<": " << (x) <<"]"<< endl
#define pii pair<int,int>
#define clr(a,b) memset((a),b,sizeof(a))
#define rep(i,a,b) for(int i = a;i < b;i ++)
#define pb push_back
#define MP make_pair
#define LL long long
#define INT(t) int t; scanf("%d",&t)
#define LLI(t) LL t; scanf("%I64d",&t)
using namespace std;
const int maxn = 1e5 + 10;
const int p = 27;
typedef unsigned long long ull;
ull c[maxn][2];
ull harsh[maxn];
int lenn;
#define lowbit(x) ((x) & (-x))
void update(int i,int flag,ull value){
while(i <= lenn){
c[i][flag] += value;
i += lowbit(i);
}
}
ull sum(int i,int flag){
ull tmp = 0;
while(i){
tmp += c[i][flag];
i -= lowbit(i);
}
return tmp;
}
int main()
{
char str[maxn];
harsh[0] = 1;
for(int i = 1;i <= maxn;i ++)
harsh[i] = harsh[i - 1] * p;
while(~scanf("%s",str + 1)){
clr(c,0);
lenn = strlen(str + 1);
for(int i = 1;i <= lenn;i ++){
update(i,0,(str[i] - 'a') * harsh[i]);
update(i,1,(str[lenn - i + 1] - 'a') * harsh[i]);
}
int n; scanf("%d",&n);
char t[20];
while(n --){
scanf("%s",t);
if(t[0] == 'p'){
int a,b; scanf("%d%d",&a,&b);
ull x = (sum(b,0) - sum(a - 1,0)) * harsh[lenn - b + 1]; /// 乘以 harsh[] 为了是两字符串到达同一水平程度,再比较
ull y = (sum(lenn - a + 1,1) - sum(lenn - b,1)) * harsh[a]; /// 最低限是 harsh[lenn - b + 1] 和 harsh[a] ,也可以同时在 +1,+2(差别也就是再同时多乘以一个27或27^2)
if(x == y){
puts("Yes");
}
else{
puts("No");
}
}
else{
int a; char b; scanf("%d %c",&a,&b);
int x = b - str[a];
update(a,0,x * harsh[a]);
update(lenn - a + 1,1,x * harsh[lenn - a + 1]);
str[a] = b;
}
}
}
return 0;
}