Subpalindromes
500ms
65536KB
This problem will be judged on Ural. Original ID:
1989
64-bit integer IO format: %lld Java class name: (Any)
64-bit integer IO format: %lld Java class name: (Any)
Font Size:
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”, 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
input | output |
---|---|
abcda 5 palindrome? 1 5 palindrome? 1 1 change 4 b palindrome? 1 5 | No Yes Yes Yes |
题意:给一个字符串,进行两个操作:
1.change i c ,把第i个换成c;
2.palindrome? i j ,询问第i个字符到第j个字符是不是回文串?
代码如下:
#include<stdio.h>
#include<string.h>
#define maxn 1100100
char str[maxn];
long long kk[maxn];
struct Node
{
int l,r;
long long s,f;
}node[maxn*4];
void hashinist()
{
int i;
kk[0]=1;
for(i=1;i<maxn;i++) kk[i]=kk[i-1]*27; //一开始乘了26,wa了......
}
Node cnt(Node a,Node b)
{
Node ans;
ans.l=a.l;
ans.r=b.r;
ans.s=a.s*kk[b.r-b.l+1]+b.s; //从l到r的字符串hash一遍
ans.f=b.f*kk[a.r-a.l+1]+a.f; //从r到l的字符串hash一遍
return ans;
}
void build(int i,int l,int r)
{
node[i].l=l;
node[i].r=r;
if(l==r)
{
node[i].s=node[i].f=str[l-1]-'a';
return ;
}
int mid=(l+r)/2;
build(i*2,l,mid);
build(i*2+1,mid+1,r);
node[i]=cnt(node[i*2],node[i*2+1]);
}
void update(int i,int j,int w)
{
if(node[i].l==node[i].r&&node[i].l==j)
{
node[i].s=node[i].f=w;
return ;
}
int mid=(node[i].l+node[i].r)/2;
if(j<=mid) update(i*2,j,w);
else update(i*2+1,j,w);
node[i]=cnt(node[i*2],node[i*2+1]);
}
Node query(int i,int l,int r)
{
if(node[i].l==l&&node[i].r==r) return node[i];
int mid=(node[i].l+node[i].r)/2;
if(mid>=r) return query(i*2,l,r);
else if(mid<l) return query(i*2+1,l,r);
else
{
Node ans;
ans=cnt(query(i*2,l,mid),query(i*2+1,mid+1,r));
return ans;
}
}
int main()
{
while(scanf("%s",str)!=EOF)
{
int n;
hashinist();
int l=strlen(str);
build(1,1,l);
scanf("%d",&n);
while(n--)
{
char z[50];
scanf("%s",z);
if(z[0]=='c')
{
int w;
char c;
scanf("%d %c",&w,&c);
update(1,w,c-'a');
}
else
{
int u,v;
scanf("%d %d",&u,&v);
Node ans;
ans=query(1,u,v);
if(ans.f==ans.s) puts("Yes");
else puts("No");
}
}
}
return 0;
}