题目链接: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. Mysql 乱码配置

    转自: http://www.ha97.com/5359.html 一.登录MySQL查看用SHOW VARIABLES LIKE ‘character%’;下字符集,显示如下: +--------- ...

  2. SecureCRT指南

    本文主要介绍SecureCRT的使用方法和技巧. [概念解释]什么是SSH? SSH的英文全称是Secure Shell 传统的网络服务程序,如:FTP和telnet在本质上都是不安全的, 因为它们在 ...

  3. ECMAScript和JavaScript的关系

    JavaScript 是一种基于 ECMAScript 规范的脚本语言,并在此基础上进行了自己的封装.ECMAScript 不是一种编程语言,仅仅是一种脚本语言规范,由欧洲计算机协会制定和发布,任何基 ...

  4. PHP源码加密- php-beast

    php-beast 详细介绍 使用案例: http://www.beastcoder.com/ PHP Beast是一个源码加密模块,使用这个模块可以把PHP源码加密并在此模块下运行. 为什么要用PH ...

  5. VS2008中的配置文件app.config简单小结

    应用程序的配置文件用于读取和保存简单的本地数据,vs中新增配置文件可以直接在项目的”属性“-”设置“里添加,添加后在项目的Properties文件夹会多出一组两个文件:Settings.setting ...

  6. easyui常用

    清空列表选中项 //easyui datagrid 清空勾选 $('#List').datagrid('clearSelections'); 扩展修改查询方法 function QueryList() ...

  7. js-限制参与活动的范围(微信H5活动)

    近期接到大连某个项目,一个H5的活动,其中有一个需求就是:这个活动的参与者仅限大连地区的用户 所以参考了微信API 得出的操作结果为: wx.ready(function() { wx.getLoca ...

  8. 洛谷 P1064 金明的预算方案【DP/01背包-方案数】

    题目背景 uim神犇拿到了uoi的ra(镭牌)后,立刻拉着基友小A到了一家--餐馆,很低端的那种. uim指着墙上的价目表(太低级了没有菜单),说:"随便点". 题目描述 不过ui ...

  9. KMP CF126B Password

    Description Asterix,Obelix和他们的临时伙伴Suffix.Prefix已经最终找到了和谐寺.然而和谐寺大门紧闭,就连Obelix的运气也没好到能打开它. 不久他们发现了一个字符 ...

  10. Flatten 2D Vector -- LeetCode

    Implement an iterator to flatten a 2d vector. For example,Given 2d vector = [ [,], [], [,,] ] By cal ...