Description


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 ≤ 105). 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.

Output


To all second type queries, you should output “Yes” on a single line if substring sj...sk is a palindrome and “No” otherwise.

Sample input

abcda
5
palindrome? 1 5
palindrome? 1 1
change 4 b
palindrome? 1 5
palindrome? 2 4

Sample onput

No
Yes
Yes
Yes

题解

使用线段树维护哈希值。

滚动哈希即rabin-karp

原hash:

\(ha[i]=ha[i-1]\times seed+s[i]\)

可以预处理出seed进位:

\(p[i]=p[i-1]\times seed\)

这样每个位置的哈希值可以直接算出。

如果要改变某个位置的字符,那么原hash值变成

\(ha[i]=p[i-1]\times ch\)

这样的hash计算无需滚动,因为计算出了进位,每一位是直接算出的。那么可以直接合并两个区间的哈希值,

即:

ha[rt]=ha[rt<<1]+ha[rt<<1|1]

改变也是单调修改,这些都是线段树的经典应用

import java.io.*;
import java.util.*; public class Main {
static final int N = (int)1e5+10;
//static final long MOD=(int)1e18+7;
static final int inf = 0x3f3f3f3f;
static char a[]=new char[N];
static long p[]=new long[N];
static long ha[]=new long[N];
static long sum[][]=new long[2][N<<2];
static void Init(int n) {
int seed=123;
p[0]=1;
for(int i=1;i<=n;i++) p[i]=(p[i-1]*seed);
}
static void PushUp(int rt,int flag) {
sum[flag][rt]=(sum[flag][rt<<1]+sum[flag][rt<<1|1]);
}
static void Build(int rt,int l,int r,int flag) {
if(l==r) {
sum[flag][rt]=ha[l];
return;
}
int mid=(l+r)>>1;
Build(rt<<1,l,mid,flag);
Build(rt<<1|1,mid+1,r,flag);
PushUp(rt,flag);
}
static void update(int a,long b,int rt,int l,int r,int flag) {
if(l==r) {
sum[flag][rt]=b;
return;
}
int mid=(l+r)>>1;
if(a<=mid) update(a,b,rt<<1,l,mid,flag);
if(a>mid) update(a,b,rt<<1|1,mid+1,r,flag);
PushUp(rt,flag);
}
static long query(int a,int b,int rt,int l,int r,int flag) {
if(a<=l&&r<=b) {
return sum[flag][rt];
}
int mid=(l+r)>>1;
long res=0;
if(a<=mid) res=(res+query(a,b,rt<<1,l,mid,flag));
if(b>mid) res=(res+query(a,b,rt<<1|1,mid+1,r,flag));
return res;
}
public static void main(String[] args) {
InputStream sysi = System.in;
OutputStream syso = System.out;
InputReader in = new InputReader(sysi);
PrintWriter out = new PrintWriter(syso);
a=in.next().toCharArray();
int m=in.nextInt();
int s,e,s1,e1,n=a.length;char ch;
Init(n);
for(int i=0;i<n;i++) ha[i+1]=((long)a[i]*p[i]);
Build(1,1,n,0);
char tmp;
for(int i=0;i<n/2;i++) {
tmp=a[i];a[i]=a[n-i-1];
a[n-i-1]=tmp;
}
for(int i=0;i<n;i++) ha[i+1]=((long)a[i]*p[i]);
Build(1,1,n,1);String str;
while(m--!=0) {
if(in.next().equals("palindrome?")) {
s=in.nextInt();e=in.nextInt();
long ha1=query(s,e,1,1,n,0);
s1=n+1-e;e1=n+1-s;
long ha2=query(s1,e1,1,1,n,1);
if(s1>s) ha1=(ha1*p[s1-s]);
else ha2=(ha2*p[s-s1]);
if(ha1==ha2) out.println("Yes");
else out.println("No");
}else {
s=in.nextInt();str=in.next();
ch=str.charAt(0);
update(s,p[s-1]*ch,1,1,n,0);
update(n+1-s,p[n-s]*ch,1,1,n,1);
}
out.flush();
}
out.close();
} static class InputReader {
public BufferedReader reader;
public StringTokenizer tokenizer; public InputReader(InputStream stream) {
reader = new BufferedReader(new InputStreamReader(stream), 32768);
tokenizer = null;
} public String next() {
while (tokenizer == null || !tokenizer.hasMoreTokens()) {
try {
tokenizer = new StringTokenizer(reader.readLine());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return tokenizer.nextToken();
} public int nextInt() {
return Integer.parseInt(next());
}
}
}

【URAL 1989】 Subpalindromes(线段树维护哈希)的更多相关文章

  1. CF213E Two Permutations 线段树维护哈希值

    当初竟然看成子串了$qwq$,不过老师的$ppt$也错了$qwq$ 由于子序列一定是的排列,所以考虑插入$1$到$m$到$n-m+1$到$n$; 如何判断呢?可以用哈希$qwq$: 我们用线段树维护哈 ...

  2. [bzoj2124]等差子序列——线段树+字符串哈希

    题目大意 给一个1到N的排列\(A_i\),询问是否存在\(p_i\),\(i>=3\),使得\(A_{p_1}, A_{p_2}, ... ,A_{p_len}\)是一个等差序列. 题解 显然 ...

  3. 洛谷 P7879 -「SWTR-07」How to AK NOI?(后缀自动机+线段树维护矩乘)

    洛谷题面传送门 orz 一发出题人(话说我 AC 这道题的时候,出题人好像就坐在我的右侧呢/cy/cy) 考虑一个很 naive 的 DP,\(dp_i\) 表示 \([l,i]\) 之间的字符串是否 ...

  4. 2016shenyang-1002-HDU5893-List wants to travel-树链剖分+线段树维护不同区间段个数

    肯定先无脑树链剖分,然后线段树维护一段区间不同个数,再维护一个左右端点的费用. 线段树更新,pushDown,pushUp的时候要注意考虑链接位置的费用是否相同 还有就是树链剖分操作的时候,维护上一个 ...

  5. Codeforces GYM 100114 D. Selection 线段树维护DP

    D. Selection Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100114 Descriptio ...

  6. [BZOJ 3995] [SDOI2015] 道路修建 【线段树维护连通性】

    题目链接:BZOJ - 3995 题目分析 这道题..是我悲伤的回忆.. 线段树维护连通性,与 BZOJ-1018 类似,然而我省选之前并没有做过  1018,即使它在 ProblemSet 的第一页 ...

  7. [BZOJ 1018] [SHOI2008] 堵塞的交通traffic 【线段树维护联通性】

    题目链接:BZOJ - 1018 题目分析 这道题就说明了刷题少,比赛就容易跪..SDOI Round1 Day2 T3 就是与这道题类似的..然而我并没有做过这道题.. 这道题是线段树维护联通性的经 ...

  8. HDU3564 --- Another LIS (线段树维护最值问题)

    Another LIS Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total ...

  9. CodeForces 343D 线段树维护dfs序

    给定一棵树,初始时树为空 操作1,往某个结点注水,那么该结点的子树都注满了水 操作2,将某个结点的水放空,那么该结点的父亲的水也就放空了 操作3,询问某个点是否有水 我们将树进行dfs, 生成in[u ...

随机推荐

  1. python实现希尔排序

    与插入排序的思想一致,插入排序是一个,希尔排序是多个插入排序! # @File: shell_sort import random def insert_sort_gap(li, d): for i ...

  2. 洛谷 P2158 [SDOI2008]仪仗队 && 洛谷 P1447 [NOI2010]能量采集

    https://www.luogu.org/problemnew/show/P2158 以人所在位置为(0,0)建立坐标系, 显然除了(0,1)和(1,0)外,可以只在坐标(x,y)的gcd(x,y) ...

  3. SPRING-BOOT系列之简介

    来自:51CTO的学习视频,本博客作为一个知识点记录以及代码验证 spring boot 特点 1. 为基于spring的开发提供更快的入门体验 2. 创建可以独立运行的spring应用 3. 直接嵌 ...

  4. Eclipse安装svn插件的几种方式 -- 转

    1.在线安装: (1).点击 Help --> Install New Software... (2).在弹出的窗口中点击add按钮,输入Name(任意)和Location(插件的URL),点击 ...

  5. Linux下cpu过高问题排查

    原文地址:https://blog.csdn.net/chenjunan888/article/details/80447800 在服务器报cpu过高时,可使用以下命令,快速导出堆栈信息,以方便查看具 ...

  6. Oracle及其相关软件历史版本下载地址

    https://edelivery.oracle.com/osdc/faces/Home.jspx 打开上面这个链接,输入自己或可用的帐号即可. 搜索到自己想要下载的软件后,点击,软件会添加到购物车中 ...

  7. phpcms v9模板制作教程

    phpcms v9模板制作教程(转载) 第一节 1.首先下载phpcms v9的集成安装包并安装,这里就不详细说明了. 2.本地调试建议大家使用APMserver,或者wampserver等,可以到P ...

  8. 【转】JobScheduler

    JobScheduler JobScheduler是Android L(API21)新增的特性,用于定义满足某些条件下执行的任务.它的宗旨是把一些不是特别紧急的任务放到更合适的时机批量处理,这样可以有 ...

  9. iphone x 高度:100%; 兼容设置

    问题: iphone x 会遇到页面设置 height:100%;之后但是底部还有一定的高度没有覆盖 解决方法: 1.让客户端设置webview的高度为100%; 2.html代码里面添加 viewp ...

  10. java实现单向链表的增、删、改、查

    单向链表 作者:vashon package com.ywx.link; /** * 单向链表 * @author vashon * */ public class LinkTest { public ...