Problem Description

刚学完后缀数组求回文串的瑶瑶(tsyao)想到了另一个问题:如果能够对字符串做一些修改,怎么在每次询问时知道以某个字符为中心的最长回文串长度呢?因为瑶瑶整天只知道LOL,当他知道自己省选成绩的时候就天天在LOL,导致现在的她实在是太弱了,根本解决不了这个问题,于是就来找你帮忙,么么哒~你就帮帮她吗

Input

第一行为一个长度不超过100000字符串s作为初始字符串。第二行一个正整数n,表示操作/询问的个数。接下来n行,每行有如下几种可能出现的操作/询问:

Insert a x  在a处字符的后面插入一个字符x

Delete a  把a处字符删除

Update a x 把a处字符改为x

Query a 查询以a为中心的最长回文串长度

Output

对于每个询问,输出得到的最长回文串长度

题目大意:略。

思路:

——————————————————————————————————————————————————————————

搬一下官方(?)题解:http://tsyao.tk/archives/94

SPLAY保存改区间从左向右的hash值和从右向左的hash值,对于每个询问,二分字符串长度。总的时间复杂度是O(qlognlogn)

——————————————————————————————————————————————————————————

处理技巧:头尾加上一个空字符可以不用考虑边界的情况。

代码(1932MS):

 #include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL; const int MAXN = ;
const int MOD = 1e8 + ;
const LL seed = ; LL base[MAXN];
char s[MAXN], op[];
int n, m; void initBase(int n = ) {
base[] = ;
for(int i = ; i <= n; ++i) base[i] = base[i - ] * seed % MOD;
} struct SplayTree {
struct Node {
int size, lhash, rhash;
char c;
Node *fa, *ch[];
};
Node statePool[MAXN], *nil, *root;
int stk[MAXN], top;
int ncnt; SplayTree() {
nil = statePool;
} void init() {
ncnt = ;
top = ;
} Node* new_node(char v, Node* f) {
Node* t;
if(top) t = &statePool[stk[--top]];
else t = &statePool[ncnt++];
t->size = ;
t->lhash = t->rhash = t->c = v;
t->ch[] = t->ch[] = nil;
t->fa = f;
return t;
} void del_node(Node* &x) {
stk[top++] = x - statePool;
x = nil;
} void update(Node* x) {
int s0 = x->ch[]->size, s1 = x->ch[]->size;
x->size = s0 + s1 + ;
x->lhash = (x->ch[]->lhash * base[s1 + ] + x->c * base[s1] + x->ch[]->lhash) % MOD;
x->rhash = (x->ch[]->rhash * base[s0 + ] + x->c * base[s0] + x->ch[]->rhash) % MOD;
} void rotate(Node* x) {
Node* y = x->fa;
int t = (y->ch[] == x);
y->fa->ch[y->fa->ch[] == y] = x; x->fa = y->fa;
y->ch[t] = x->ch[t ^ ]; x->ch[t ^ ]->fa = y;
x->ch[t ^ ] = y; y->fa = x;
update(y);
} void splay(Node* x, Node* f) {
while(x->fa != f) {
if(x->fa->fa == f) rotate(x);
else {
Node *y = x->fa, *z = y->fa;
if((z->ch[] == y) == (y->ch[] == x)) rotate(y);
else rotate(x);
rotate(x);
}
}
update(x);
if(x->fa == nil) root = x;
} Node* kth(int k) {
Node* x = root;
while(true) {
int t = x->ch[]->size + ;
if(t == k) break;
if(t > k) x = x->ch[];
else x = x->ch[], k -= t;
}
return x;
} void build(Node* &x, Node* f, int l, int r) {
int mid = (l + r) >> ;
x = new_node(s[mid], f);
if(l < mid) build(x->ch[], x, l, mid - );
if(mid < r) build(x->ch[], x, mid + , r);
update(x);
} void insert(int pos, char c) {
splay(kth(pos), nil);
splay(kth(pos + ), root);
root->ch[]->ch[] = new_node(c, root->ch[]);
update(root->ch[]); update(root);
} void modify(int pos, char c) {
splay(kth(pos), nil);
root->c = c;
update(root);
} void remove(int pos) {
splay(kth(pos - ), nil);
splay(kth(pos + ), root);
del_node(root->ch[]->ch[]);
update(root->ch[]); update(root);
} bool check(int pos, int len) {
splay(kth(pos - len - ), nil);
splay(kth(pos + len + ), root);
splay(kth(pos), root->ch[]);
Node* x = root->ch[]->ch[];
return x->lhash == x->rhash;
} int query(int pos) {
int l = , r = min(pos - , root->size - - pos) + ;
while(l < r) {
int mid = (l + r) >> ;
if(check(pos, mid)) l = mid + ;
else r = mid;
}
return * l - ;
} void debug(Node* x) {
static int t = ;
if(x == root) printf("Debug %d\n", ++t);
printf("val:%d lson:%d rson:%d lhash:%d rhash:%d\n", x - statePool, x->ch[] - statePool, x->ch[] - statePool, x->lhash, x->rhash);
if(x->ch[] != nil) debug(x->ch[]);
if(x->ch[] != nil) debug(x->ch[]);
}
} splay; int main() {
scanf("%s", s + );
n = strlen(s + );
initBase();
splay.init();
splay.build(splay.root, splay.nil, , n + );
scanf("%d", &m);
char c;
for(int i = , a; i < m; ++i) {
scanf("%s%d", op, &a);
++a;
if(strcmp(op, "Insert") == ) {
scanf(" %c", &c);
splay.insert(a, c);
}
if(strcmp(op, "Delete") == )
splay.remove(a);
if(strcmp(op, "Update") == ) {
scanf(" %c", &c);
splay.modify(a, c);
}
//splay.debug(splay.root);
if(strcmp(op, "Query") == )
printf("%d\n", splay.query(a));
}
}

ACdream 1104 瑶瑶想找回文串(SplayTree + Hash + 二分)的更多相关文章

  1. [CSP-S模拟测试]:回文串(hash+二分)

    题目描述 $ASDFZ$的机房中不仅有红太阳,还有蓝太阳和原谅色太阳.有一天,太阳们来到机房,发现桌上有不知道哪个蒟蒻放上的问题:令$F(A,B)$表示选择一个串$A$的非空前缀$S$和串$B$的非空 ...

  2. HDU - 6156 2017CCPC网络赛 Palindrome Function(数位dp找回文串)

    Palindrome Function As we all know,a palindrome number is the number which reads the same backward a ...

  3. bzoj 3676 回文串 manachar+hash

    考虑每个回文串,它一定是它中心字母的最长回文串两侧去掉同样数量的字符后的一个子串. 所以我们可以用manachar求出每一位的回文半径,放到哈希表里并标记出它的下一个子串. 最后拓扑排序递推就行了.. ...

  4. POWEROJ 2610 判断回文串 【HASH】

    题目链接[https://www.oj.swust.edu.cn/problem/show/2610] 题意:给你一个字符串,让你判断这个字符串是不是回文串,字符串的长度是1<len<1e ...

  5. [BZOJ4755][JSOI2016]扭动的回文串(manacher+Hash)

    前两种情况显然直接manacher,对于第三种,枚举回文中心,二分回文半径,哈希判断即可. #include<cstdio> #include<algorithm> #defi ...

  6. POJ--3974 Palindrome(回文串,hash)

    链接:点击这里 #include<iostream> #include<algorithm> #include<stdio.h> #include<cstri ...

  7. 【回文串-Manacher】

    Manacher算法能够在O(N)的时间复杂度内得到一个字符串以任意位置为中心的回文子串.其算法的基本原理就是利用已知回文串的左半部分来推导右半部分. 转:http://blog.sina.com.c ...

  8. 【BZOJ】【2565】最长双回文串

    Manacher算法 找出一个最长子串S=X+Y,且X和Y都是回文串,求最长的长度是多少…… 同时找两个串明显很难搞啊……但是我们可以先找到所有的回文串!在找回文串的同时我们可以预处理出来l[i]和r ...

  9. 回文串 --- 动态dp UVA 11584

    题目链接: https://cn.vjudge.net/problem/34398/origin 本题的大意其实很简单,就是找回文串,大致的思路如下: 1. 确定一个回文串,这里用到了自定义的chec ...

随机推荐

  1. FTS抓包看蓝牙验证的过程

    1.概述    在进行蓝牙设备的连接时,为了保护个人隐私和数据保密的需要,需要进行验证.   2.一些Frame Frame74:本地发送Authentication requset command ...

  2. 蓝牙BLE ATT剖析(一)

    一.概述 The attribute protocol allows a device referred to as the server to expose a set of attributes ...

  3. Visual Studio 2005安装qt-win-commercial-src-4.3.1,并设置环境变量

    虽然已经在Visual Studio 2005下安装Qt4已经n次了,还是打算在上写写安装方法. qt-win-commercial-src-4.3.1.zip.qt-vs-integration-1 ...

  4. 管子&小白

    管夷吾已入朝,稽首谢罪,桓公亲手扶起,赐之以坐.夷吾曰:“臣乃俘戮之余,得蒙宥死,实为万幸,敢辱过礼!”桓公曰:“寡人有问于子,子必坐,然后敢请."夷吾再拜就坐. 桓公曰:“齐,千乘之国,先 ...

  5. 规则html表单对象赋值

    function grid_load_callback(data, status) {            if (data.rows.length > 0)            {     ...

  6. strcpy之代码的健壮性与可维护性

    strcpy   函数的原型是: char * strcpy(char * strDest,const char * strSrc);    功能:把从strSrc地址开始且含有NULL结束符的字符串 ...

  7. magento 切换数据库,使用不同数据库

    1. 在app/etc/local.xml 中,添加新的数据库选项 <?xml version="1.0"?> <config> <global> ...

  8. [LeetCode]题解(python):082 - Remove Duplicates from Sorted List II

    题目来源 https://leetcode.com/problems/remove-duplicates-from-sorted-list-ii/ Given a sorted linked list ...

  9. eclipse中tomcat能正常启动,但是浏览器访问不了tomcat首页

    在eclipse中新建tomcat7,完成后tomcat能够正常启动,但是浏览器问题localhost:8080访问不了. 解决方法如下: 双击eclipse中服务器中的tomcat 出现tomcat ...

  10. 56个睿智帅气貌美的CTO大牛陪你叨逼叨

    技术领域门槛高,苦读十年有时不如大牛一指点 可CTO级别的大牛何处找? 别急,别急 他们1月12日都去参加APICloud新品发布会了! (没图说啥子) 各路大牛们云集,不仅是为APICloud新品发 ...