ACdreamoj 1011(树状数组维护字符串hash前缀和)
题目链接: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前缀和)的更多相关文章
- 【BZOJ2124】等差子序列 树状数组维护hash值
[BZOJ2124]等差子序列 Description 给一个1到N的排列{Ai},询问是否存在1<=p1<p2<p3<p4<p5<…<pLen<=N ...
- 第十二届湖南省赛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 ...
- BZOJ 3881 [COCI2015]Divljak (Trie图+Fail树+树链的并+树状数组维护dfs序)
题目大意: Alice有n个字符串S_1,S_2...S_n,Bob有一个字符串集合T,一开始集合是空的. 接下来会发生q个操作,操作有两种形式: “1 P”,Bob往自己的集合里添加了一个字符串P. ...
- [poj3378] Crazy Thairs (DP + 树状数组维护 + 高精度)
树状数组维护DP + 高精度 Description These days, Sempr is crazed on one problem named Crazy Thair. Given N (1 ...
- HDU 5869 Different GCD Subarray Query (GCD种类预处理+树状数组维护)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5869 问你l~r之间的连续序列的gcd种类. 首先固定右端点,预处理gcd不同尽量靠右的位置(此时gc ...
- POJ 3321 Apple Tree(后根遍历将树转化成序列,用树状数组维护)
题意:一棵树,有很多分叉,每个分叉上最多有1个苹果. 给出n,接下来n-1行,每行u,v,表示分叉u,v之间有树枝相连.这里数据中u相当于树中的父节点,v相当于子节点. 给出两个操作: 1.C x ...
- LOJ107. 维护全序集【树状数组维护全序集】
题目描述 这是一道模板题,其数据比「普通平衡树」更强. 如未特别说明,以下所有数据均为整数. 维护一个多重集 S ,初始为空,有以下几种操作: 把 x 加入 S 删除 S 中的一个 x,保证删除的 x ...
- ACM-ICPC 2018 徐州赛区网络预赛 G. Trace【树状数组维护区间最大值】
任意门:https://nanti.jisuanke.com/t/31459 There's a beach in the first quadrant. And from time to time, ...
- 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 ...
随机推荐
- Hibernate的注释该如何使用?每一个注释代表什么意思?
出自:java快快飞 原文地址:http://blog.sina.com.cn/s/blog_697b968901016s31.html Hibernate的注释该如何使用?每一个注释代表什么意思? ...
- 理解S12(X)架构中的地址映射方案
目录 1. 介绍 2. CPU 本地地址 3. 分页窗口 4. 内存页 5. 控制各个对象在内存中放置的位置 介绍 在一个S12或S12X架构中,很有必要分清楚两种类型的内存地址:banked和non ...
- lca板子
#include<cstdio> #include<cstring> #include<algorithm> #define LL long long using ...
- Js String 属性扩展
String.prototype.startsWith = function (startStr) { var d = startStr.length; return (d >= 0 &am ...
- [bzoj2111][ZJOI2010]Perm 排列计数 ——问题转换,建立数学模型
题目大意 称一个1,2,...,N的排列P1,P2...,Pn是Magic的,当且仅当2<=i<=N时,Pi>Pi/2. 计算1,2,...N的排列中有多少是Magic的,答案可能很 ...
- 用MysQL语句怎么进行远程连接数据库
一.连接远程数据库: 1.显示密码如:MySQL 连接远程数据库(192.168.2.115),端口“3306”,用户名为“root”,密码“root” C: -u root -proot (注意第一 ...
- wav格式
转自: http://www.cnblogs.com/tiandsp/archive/2012/10/17/2728585.html 起始地址 占用空间 本地址数字的含义 00H 4byte RIFF ...
- Linux中断(interrupt)子系统之五:软件中断(softIRQ)【转】
转自:http://blog.csdn.net/droidphone/article/details/7518428 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[-] 软件中 ...
- SpringMvc+Spring+Mybatis+Maven整合
一.建立数据库表,使用generator自动生成相关代码: /* SQLyog Ultimate v11.24 (32 bit) MySQL - 5.1.62-community : Database ...
- HDU 6108.小C的倍数问题 (2017"百度之星"程序设计大赛 - 初赛(A)1001)
补完题?不存在的. 这么久了,还是一条咸鱼,看一堆乱七八糟的东西,写一堆没用的水题,一点进步都没有,还是那么菜,菜的掉渣. 这个百毒之星初赛A还会写两道最简单的水题,初赛B一点也不会,菜的难过... ...