AC dreamoj 1011 树状数组+hash维护字符串的前缀和
2014-12-26 16:12
507 查看
http://acdream.info/problem?pid=1019
Now we have a long long string, and we will have two kinds of operation on it.
C i y : change the ith letter to y.
Q i j : check whether the substring from ith letter to jth letter is a palindrome.
There are multiple test cases.
The first line contains a string whose length is not large than 1,000,000.
The next line contains a integer N indicating the number of operations.
The next N lines each lines contains a operation.
All letters in the input are lower-case.
For each query operation, output "yes" if the corresponding substring is a palindrome, otherwise output "no".
Problem Description
Now we have a long long string, and we will have two kinds of operation on it.C i y : change the ith letter to y.
Q i j : check whether the substring from ith letter to jth letter is a palindrome.
Input
There are multiple test cases.The first line contains a string whose length is not large than 1,000,000.
The next line contains a integer N indicating the number of operations.
The next N lines each lines contains a operation.
All letters in the input are lower-case.
Output
For each query operation, output "yes" if the corresponding substring is a palindrome, otherwise output "no".
Sample Input
aaaaa 4 Q 1 5 C 2 b Q 1 5 Q 1 3
Sample Output
yes no yes
/** ACdreamoj 1019 树状数组+hash维护字符串的前缀和 题目大意: 给定一个字符串,单点更新,区间查询该区间是不是回文串。 解题思路: hash是x1 * p^1+ x2*p^2 +x3*p^3...可以用树状数组维护前缀和, 维护两个串,一个是正串,另一个是反串用于比较。 字符串区间s[l~r]的哈希值为sum(s[r]-s[l-1])/Hash[l-1]; */ #include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> using namespace std; typedef unsigned long long LL; const int maxn=1000010; const int seed=13; LL Hash[maxn],C[2][maxn]; char s[maxn]; int len; void init() { Hash[0]=1; for(int i=1;i<maxn;i++) Hash[i]=Hash[i-1]*seed; } int lowbit(int x) { return x&(-x); } void add(int i,int x,LL pos) { while(x<=len) { C[i][x]+=pos; x+=lowbit(x); } } LL sum(int i,int x) { LL ans=0; while(x) { ans+=C[i][x]; x-=lowbit(x); } return ans; } LL gethash(int i,int l,int r) { return sum(i,r)-sum(i,l-1); } int main() { init(); while(~scanf("%s",s+1)) { memset(C,0,sizeof(C)); len=strlen(s+1); for(int i=1;i<=len;i++) { add(0,i,(s[i]-'a')*Hash[i]); add(1,len+1-i,(s[i]-'a')*Hash[len+1-i]); } int T; cin >> T; while(T--) { char c[5]; scanf("%s",c); if(c[0]=='C') { char b[5]; int a; scanf("%d%s",&a,b); add(0,a,(b[0]-s[a])*Hash[a]); add(1,len+1-a,(b[0]-s[a])*Hash[len+1-a]); s[a]=b[0]; } else { int l,r; scanf("%d%d",&l,&r); if(gethash(0,l,r)*Hash[len-r]==gethash(1,len+1-r,len+1-l)*Hash[l-1])//采用交叉相乘把除换成了乘 puts("yes"); else puts("no"); } } } return 0; }
相关文章推荐
- ACdreamoj 1011(树状数组维护字符串hash前缀和)
- ACdreamoj 1011(树状数组维护字符串hash前缀和)
- ACdream OJ 1154 Lowbit Sum
- acdreamoj 1211 有上下界的网络流
- ACdream OJ 1099 瑶瑶的第K大 --分治+IO优化
- 【ACdream OJ 1099 - 瑶瑶的第K大 (输入优化+手写O(n)快排)】
- acdreamoj1112 sg函数
- Acdreamoj1115(数学思维称号)
- acdreamOJ 1108分块算法
- 一道超级坑爹的水题(ACdream oj 无耻的出题人)
- Acdreamoj1115(数学思维题)
- ACdream OJ 1153 (k-GCD)
- ACdreamOJ 1154 Lowbit Sum (数位dp)
- 用“道”的思想解决费用流问题---取/不取皆是取 (有下界->有上界) / ACdreamoj 1171
- ACdream OJ 1099 瑶瑶的第K大 --分治+IO优化 - whatbeg
- ACdreamoj(1105)模拟题
- 用“道”的思想解决费用流问题---取/不取皆是取 (有下界->有上界) / ACdreamoj 1171
- ACdreamOJ 1154 Lowbit Sum (数字dp)
- ACdreamoj1110(多重背包)
- acdreamoj 瑶瑶饿了 完全背包