题目链接:http://acdream.info/problem?

pid=1019

题意:两种操作,第一种将字符串某个位置的字符换为还有一个字符。另外一种查询某个连续子序列是否是回文串;

解法:有两种hash的办法,所以写了两种解法;首先hash是x1 * p^1+ x2*p^2 +x3*p^3...能够用树状数组维护前缀和,维护两个串,一个是正串。还有一个是反串用于比較。比較时候乘以对应的p倍数推断是否相等。

刘汝佳白书上的hash方法处理这道题更复杂:改动i会对后缀j产生的影响为a*p^(i-j),那么把这个式子变成a * p^i *p^(-j)  然后就是在这个位置加上a * p^i,以后查询每一个i位置的hash值后都乘以p^i.

第一分代码:

/******************************************************
* @author:xiefubao
*******************************************************/
#pragma comment(linker, "/STACK:102400000,102400000")
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <vector>
#include <algorithm>
#include <cmath>
#include <map>
#include <set>
#include <stack>
#include <string.h>
//freopen ("in.txt" , "r" , stdin);
using namespace std; #define eps 1e-8
#define zero(_) (abs(_)<=eps)
const double pi=acos(-1.0);
typedef unsigned long long LL;
const int Max=1000010;
const int INF=1e9+7;
char s[Max];
LL C[2][Max];
LL Hash[Max];
int seed=13;
void init()
{
Hash[0]=1;
for(int i=1; i<Max; i++)
Hash[i]=Hash[i-1]*seed;
}
int len;
void update(int i,int pos,LL data)
{
while(pos<=len)
{
C[i][pos]+=data;
pos+=pos&(-pos);
}
}
LL get(int i,int pos)
{
LL ans=0;
while(pos)
{
ans+=C[i][pos];
pos-=pos&(-pos);
}
return ans;
}
LL gethash(int i,int l,int r)
{
return get(i,r)-get(i,l-1);
}
int main()
{
init();
while(scanf("%s",s+1)==1)
{
memset(C,0,sizeof C);
int t;
cin>>t;
len=strlen(s+1);
for(int i=1; i<=len; i++)
{
update(0,i,(s[i]-'a')*Hash[i]);
update(1,len+1-i,(s[i]-'a')*Hash[len+1-i]);
}
while(t--)
{
char c;
getchar();
scanf("%c",&c);
if(c=='C')
{
char b[5];
int a;
scanf("%d%s",&a,b);
update(0,a,-(s[a]-'a')*Hash[a]);
update(0,a,(b[0]-'a')*Hash[a]);
update(1,len+1-a,-(s[a]-'a')*Hash[len+1-a]);
update(1,len+1-a,(b[0]-'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-l]==gethash(1,len+1-r,len+1-l)*Hash[r-1])
puts("yes");
else
puts("no");
}
}
}
return 0;
}

第二份代码:

/******************************************************
* @author:xiefubao
*******************************************************/
#pragma comment(linker, "/STACK:102400000,102400000")
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <vector>
#include <algorithm>
#include <cmath>
#include <map>
#include <set>
#include <stack>
#include <string.h>
//freopen ("in.txt" , "r" , stdin);
using namespace std; #define eps 1e-8
#define zero(_) (abs(_)<=eps)
const double pi=acos(-1.0);
typedef unsigned long long LL;
const int Max=1000010;
const LL INF=1000000007;
char s[Max];
char s2[Max];
LL Hash[Max];
LL C[Max];
LL C2[Max];
int seed=13;
int len;
void init()
{
Hash[0]=1;
for(int i=1; i<Max; i++)
Hash[i]=(Hash[i-1]*seed)%INF;
}
LL pow1(LL a,LL k)
{
LL ans=1;
while(k)
{
if(k&1)
ans=(ans*a)%INF;
a=(a*a)%INF;
k>>=1;
}
return ans;
}
void update(int pos,LL value)
{
while(pos!=0)
{
C[pos]=(C[pos]+value+INF)%INF;
pos-=pos&(-pos);
}
}
void update2(int pos,LL value)
{
while(pos!=0)
{
C2[pos]=(C2[pos]+value+INF)%INF;
pos-=pos&(-pos);
}
}
LL query(int pos)
{
LL ans=0;
while(pos<=len+1)
{
ans=(ans+C[pos])%INF;
pos+=pos&(-pos);
}
return ans;
}
LL query2(int pos)
{
LL ans=0;
while(pos<=len+1)
{
ans=(ans+C2[pos])%INF;
pos+=pos&(-pos);
}
return ans;
}
LL get(int now)
{
LL ans=query(now);
return (pow1(pow1(seed,now),INF-2)%INF*ans)%INF;
}
LL gethash(int l,int r)
{
return (get(l)-get(r+1)*Hash[r+1-l]%INF+INF)%INF;
}
LL get2(int now)
{
LL ans=query2(now);
return (pow1(pow1(seed,now),INF-2)%INF*ans)%INF;
}
LL gethash2(int l,int r)
{
return (get2(l)-get2(r+1)*Hash[r+1-l]%INF+INF)%INF;
}
int main()
{
init();
while(scanf("%s",s+1)==1)
{
int t;
scanf("%d",&t);
len=strlen(s+1);
strcpy(s2+1,s+1);
reverse(s2+1,s2+len+1);
memset(C,0,sizeof C);
memset(C2,0,sizeof C2);
for(int i=1; i<=len; i++)
{
update(i,(s[i]-'a')*Hash[i]%INF);//a*x^(i-j)=a*x^i*(x^-j);
update2(i,(s2[i]-'a')*Hash[len+1-i]%INF);
}
while(t--)
{
char c[5];
scanf("%s",c);
//printf(c);
if(c[0]=='C')
{
int a;
char b[5];
scanf("%d%s",&a,b);
update(a,('a'-s[a])*Hash[a]%INF);
update(a,(b[0]-'a')*Hash[a]%INF);
update2(len+1-a,('a'-s2[len+1-a])*Hash[len+1-a]%INF);
update2(len+1-a,(b[0]-'a')*Hash[len+1-a]%INF);
s[a]=b[0];
s2[len+1-a]=b[0];
}
else
{
int l;
int r;
scanf("%d%d",&l,&r);
if(r-l<=1)
{
puts("yes");
continue;
}
if(gethash(l,r)==gethash2(len+1-r,len+1-l))
puts("yes");
else
puts("no");
}
}
}
return 0;
}

ACdreamoj 1011(树状数组维护字符串hash前缀和)的更多相关文章

  1. 【BZOJ2124】等差子序列 树状数组维护hash值

    [BZOJ2124]等差子序列 Description 给一个1到N的排列{Ai},询问是否存在1<=p1<p2<p3<p4<p5<…<pLen<=N ...

  2. 第十二届湖南省赛G - Parenthesis (树状数组维护)

    Bobo has a balanced parenthesis sequence P=p 1 p 2…p n of length n and q questions. The i-th questio ...

  3. BZOJ 3881 [COCI2015]Divljak (Trie图+Fail树+树链的并+树状数组维护dfs序)

    题目大意: Alice有n个字符串S_1,S_2...S_n,Bob有一个字符串集合T,一开始集合是空的. 接下来会发生q个操作,操作有两种形式: “1 P”,Bob往自己的集合里添加了一个字符串P. ...

  4. [poj3378] Crazy Thairs (DP + 树状数组维护 + 高精度)

    树状数组维护DP + 高精度 Description These days, Sempr is crazed on one problem named Crazy Thair. Given N (1 ...

  5. HDU 5869 Different GCD Subarray Query (GCD种类预处理+树状数组维护)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5869 问你l~r之间的连续序列的gcd种类. 首先固定右端点,预处理gcd不同尽量靠右的位置(此时gc ...

  6. POJ 3321 Apple Tree(后根遍历将树转化成序列,用树状数组维护)

    题意:一棵树,有很多分叉,每个分叉上最多有1个苹果. 给出n,接下来n-1行,每行u,v,表示分叉u,v之间有树枝相连.这里数据中u相当于树中的父节点,v相当于子节点. 给出两个操作: 1.C x  ...

  7. LOJ107. 维护全序集【树状数组维护全序集】

    题目描述 这是一道模板题,其数据比「普通平衡树」更强. 如未特别说明,以下所有数据均为整数. 维护一个多重集 S ,初始为空,有以下几种操作: 把 x 加入 S 删除 S 中的一个 x,保证删除的 x ...

  8. ACM-ICPC 2018 徐州赛区网络预赛 G. Trace【树状数组维护区间最大值】

    任意门:https://nanti.jisuanke.com/t/31459 There's a beach in the first quadrant. And from time to time, ...

  9. Playrix Codescapes Cup (Codeforces Round #413, rated, Div. 1 + Div. 2) C. Fountains 【树状数组维护区间最大值】

    题目传送门:http://codeforces.com/contest/799/problem/C C. Fountains time limit per test 2 seconds memory ...

随机推荐

  1. JS省份联级下拉框

    <script type="text/javascript"> var china=new Object();china['北京市']=new Array('北京市区' ...

  2. symfony 关于nginx的配置问题

    好久没有使用symfony,今天想重新宠幸的时候,却碰到了一个很尴尬的问题,下载安装好symfony的时候访问首页成功安装,然而写了一个其它的路由却怎么都是404. 官网看了n遍的路由配置,什么开始第 ...

  3. [字符串] StartWith和EndWith效率比较低

    之前无意中看到有人提到StartWith和EndWith效率比较低,今天恰好有用到这样的场景,于是写了个测试验证一下. 该示例仅在比较字符串首尾单个字符,用途有限. var str = "\ ...

  4. error MSB3073 解决方法(转)

    原文转自 http://blog.csdn.net/yangjie569889321/article/details/28488151 最近将VC2002 代码移植到VC2010,出现编译错误:1&g ...

  5. cocos2d学习网址

    http://python.cocos2d.org/doc/programming_guide/index.html http://bbs.tairan.com/article-25-1.html h ...

  6. 【原创】Linux环境下的图形系统和AMD R600显卡编程(9)——R600显卡的3D引擎和图形流水线

    1. R600 3D引擎 R600核心是AMD一款非常重要的GPU核心,这个核心引入了统一处理器架构,其寄存器和指令集同以前的GPU 都完全不同,对其编程也有比较大的区别. 图1显示了R600 GPU ...

  7. 基于Xen实现一种domain0和domainU的应用层数据交互高效机制 - 3

    继续 上一篇 的研究,结合 xen4.2.3 的代码分析,发现 xen4.2.3 的应用层工具库 tools 包含一个工具叫 libvchan ,其头文件描述如下: * This is a libra ...

  8. resin启动问题

    启动resin时报错如下: Resin/4.0.28 can't restart -server 'app-0'. com.caucho.bam.RemoteConnectionFailedExcep ...

  9. Less的用法

    Less常用来写样式,比较多的用法是使用第三方软件编译成CSS文件,然后在HTML页面引入CSS文件.而不是直接在HTML页面里引入编译文件和Less文件.如此以来,在后期修改方便的多.当然,在写小项 ...

  10. 鸭子-策略模式(Strategy)

    前言 万事开头难,最近对这句话体会深刻!这篇文章是这个系列正式开始介绍设计模式的第一篇,所以肩负着确定这个系列风格的历史重任,它在我脑袋里默默地酝酿了好多天,却只搜刮出了一点儿不太清晰的轮廓,可是时间 ...