Gym 100570E : Palindrome Query
De Prezer loves palindrome strings. A string s1s2...sn is palindrome if and only if it is equal to its reverse.
De Prezer also loves queries.
You are given string s of length n and m queries. There are 3 types of queries :
1. 1px : Modify sp = x where 1 ≤ p ≤ n and x is a lower case English letter.
2. 2p : Print the length of the largest palindrome substring of s like slsl + 1...sr such that l ≤ p ≤ r and r - p = p - l. (1 ≤ p ≤ n)
3. 3p : Print the length of the largest palindrome substring of s like slsl + 1...sr such that l ≤ p and p + 1 ≤ r and r - p - 1 = p - l. (1 ≤ p ≤ n - 1) or - 1 if there is no such substring.
The first line of input contains s and m.
Next m lines contain queries.
1 ≤ n, m ≤ 105
s only contains lower case English letters.
For each query of type 2 and 3 print the answer in a single line.
解题报告:
大意就是给你一个字符串,有三种操作:
操作1:将某个位置的字符改成另外一个字符
操作2:询问以位置 x 为中点的奇回文串长度
操作3:询问以位置 x,x+1为中的偶回文串长度
我们建立一颗线段树来解决这个问题
线段树中的存储的 key1 表示 s[L] * p^0 + S[L+1] * p ^1 + ..... S[R] * p ^ (R-L) , key2 值表示S[R] * p ^ 0 + S[R-1] * p ^1 + ...S[L] * p^(R-L)
显然key2 是倒着的,这样方便我们查询这个区间是否是回文子串
题目显然要求是单点更新,区间查询.
对于单点更新而言,最重要的就是push_up函数,我们考虑
将[L,mid] 和 [mid + 1 , R]进行合并时,注意到key值的含义,我们需要给右边的[mid+1,R]的key1值乘上p^(mid-L+1),key2则是给[L,mid]乘上p ^(R-mid+1)
那么更新我们就解决了,查询呢
下面皆以 key1 为例(key2同理可得)
对于key1而言,我们主要就是要给落在右边的查询区间段上的乘上一个值.
假设我们现在要查询的区间段是[ ql , qr ] ,此时所在的线段是[L,R],中点是mid , 我们假设 qr > mid(即有落在右边的部分)
那么我们需要给右边乘的值就是p ^ (mid - ql + 1) <仔细想想>
key2同理可得,这里不再累述
这样我们就解决了查询问题,那么对于每个询问,我们二分答案即可
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <queue>
#include <iomanip>
#include <string>
#include <ctime>
typedef unsigned char byte;
#define pb push_back
#define input_fast std::ios::sync_with_stdio(false);std::cin.tie(0)
#define local freopen("in.txt","r",stdin)
#define pi acos(-1) using namespace std;
typedef pair<unsigned int ,unsigned int> dl;
const int maxn = 1e5 + ;
const unsigned int p1 = ;
const unsigned int p2 = ;
unsigned int value1[maxn];
unsigned int value2[maxn]; typedef struct treenode
{
int l , r ;
dl key1,key2;
void updata(unsigned int v)
{
key1.first = key1.second = v;
key2.first = key2.second = v;
} }; treenode tree[maxn * ]; inline void build_tree(int o,int l,int r)
{
tree[o].l = l , tree[o].r = r , tree[o].key1.first = tree[o].key1.second = tree[o].key2.first = tree[o].key2.second = ;
if (r > l)
{
int mid = l + (r-l)/;
build_tree(*o,l,mid);
build_tree(*o+,mid+,r);
}
} inline void push_up(int o)
{
int ac = tree[*o].r - tree[*o].l + ;
int ac2 = tree[*o+].r - tree[*o+].l + ;
tree[o].key1.first = tree[*o].key1.first + tree[*o+].key1.first * value1[ac];
tree[o].key1.second = tree[*o].key1.second + tree[*o+].key1.second * value2[ac];
tree[o].key2.first = tree[*o].key2.first * value1[ac2] + tree[*o+].key2.first;
tree[o].key2.second = tree[*o].key2.second * value2[ac2] + tree[*o+].key2.second;
} void updata(int ql,int qr,int o,unsigned int v)
{
int l = tree[o].l , r = tree[o].r;
if (ql <= l && qr >= r)
tree[o].updata(v);
else
{
int mid = l + (r-l) / ;
if (mid >= ql)
updata(ql,qr,*o,v);
if (mid < qr)
updata(ql,qr,*o+,v);
push_up(o);
}
} dl query(int ql,int qr,int o,int type)
{
int l = tree[o].l , r = tree[o].r;
//cout << "L is " << l << " R is " << r << " ql is " << ql << " qr is " << qr << endl;
if (ql == l && qr == r)
{
if (type == ) return tree[o].key1;
else return tree[o].key2;
}
else
{
int mid = l + (r-l) / , ac;
dl res(,) , temp;
if (mid >= ql)
{
int atr = min(mid,qr);
temp = query(ql,atr,*o,type);
if (type == && qr - mid > )
{
temp.first *= value1[qr - mid];
temp.second *= value2[qr - mid];
}
res.first += temp.first;
res.second += temp.second;
}
if (mid < qr)
{
int ltr = max(ql,mid+);
temp = query(ltr,qr,*o+,type);
if (type == && mid - ql + > )
{
temp.first *= value1[mid - ql + ];
temp.second *= value2[mid - ql + ];
}
res.first += temp.first;
res.second += temp.second;
}
//cout << "L is " << l << " R is " << r << " fist-value is " << res.first << " second-value is " << res.second << endl;
return res;
}
} char str[maxn] , temp[];
int length , m ; bool equaldl(dl x,dl y)
{
return x.first == y.first && x.second == y.second;
} int main(int argc,char *argv[])
{
scanf("%s%d",str,&m);
value1[] = value2[] = ;
length = strlen(str);
build_tree(,,length-);
for(int i = ; i <= length ; ++ i)
{
value1[i] = value1[i-]*p1;
value2[i] = value2[i-]*p2;
}
for(int i = ; i < length ; ++ i) updata(i,i,,(unsigned int)str[i]);
while(m--)
{
int type,x;
scanf("%d",&type);
if (type == )
{
scanf("%d%s",&x,temp);
x--;
str[x] = temp[];
updata(x,x,,temp[]);
}
else
{
scanf("%d",&x);
int L , R;
x--;
if (type == )
{
L = , R = min( x + , length - x );
while(L < R)
{
int mid = L + (R-L+) / ;
int tl = x - mid + ;
int tr = x + mid - ;
if (equaldl(query(tl,tr,,),query(tl,tr,,))) L = mid;
else R = mid - ;
}
printf("%d\n",*L-);
}
else
{
if (x+ >= length || str[x] != str[x+]) printf("-1\n");
else
{
int L = , R = min(x + , length - x - );
while(L < R)
{
int mid = L + (R-L+) / ;
int tl = x - mid + ;
int tr = x + mid;
if (equaldl(query(tl,tr,,),query(tl,tr,,))) L = mid;
else R = mid - ;
}
printf("%d\n",*L);
}
}
}
}
return ;
}
Gym 100570E : Palindrome Query的更多相关文章
- Codeforces Gym 100570 E. Palindrome Query Manacher
E. Palindrome QueryTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100570/pro ...
- Gym - 100570E:Palindrome Query (hash+BIT+二分维护回文串长度)
题意:给定字符串char[],以及Q个操作,操作有三种: 1:pos,chr:把pos位置的字符改为chr 2:pos:问以pos为中心的回文串长度为多长. 3:pos:问以pos,pos+1为中心的 ...
- codeforce Gym 100570B ShortestPath Query (最短路SPFA)
题意:询问单源最短路径,每条边有一个颜色,要求路径上相邻边的颜色不能相同,无重边且边权为正. 题解:因为路径的合法性和边的颜色有关, 所以在做spfa的时候,把边丢到队列中去,松弛的时候注意判断一下颜 ...
- Gym - 100676F Palindrome —— 并查集
题目链接:https://vjudge.net/contest/155789#problem/E 题解: 由于是回文串,所以可以先将在对称位置的字符放在同一个集合(如果期间有两个非‘?’,且不相等,则 ...
- Solution -「Gym 102759I」Query On A Tree 17
\(\mathcal{Description}\) Link. 给定一棵含 \(n\) 个结点的树,结点 \(1\) 为根,点 \(u\) 初始有点权 \(a_u=0\),维护 \(q\) 次 ...
- Codeforces Gym 100571A A. Cursed Query 离线
A. Cursed QueryTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100571/problem ...
- Gym 100952H&&2015 HIAST Collegiate Programming Contest H. Special Palindrome【dp预处理+矩阵快速幂/打表解法】
H. Special Palindrome time limit per test:1 second memory limit per test:64 megabytes input:standard ...
- Gym 100952C&&2015 HIAST Collegiate Programming Contest C. Palindrome Again !!【字符串,模拟】
C. Palindrome Again !! time limit per test:1 second memory limit per test:64 megabytes input:standar ...
- Gym 100952 H. Special Palindrome
http://codeforces.com/gym/100952/problem/H H. Special Palindrome time limit per test 1 second memory ...
随机推荐
- puppet foreman
服务器(物理机器和虚拟机)多了以后需要工具来管理,经常登陆系统后不知是在虚拟机上还是在物理机上?如果在虚拟机上这个虚拟机运行在哪个服务器节 点(host)上?如果在物理机上运行在什么配置的物理机上?运 ...
- poj1011 Sticks(dfs+剪枝)
Sticks Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 110416 Accepted: 25331 Descrip ...
- (转)iOS Wow体验 - 第七章 - 操作图例与触屏人机工学
本文是<iOS Wow Factor:Apps and UX Design Techniques for iPhone and iPad>第七章译文精选,其余章节将陆续放出.上一篇:Wow ...
- Android BLE开发之Android手机与BLE终端通信
本文来自http://blog.csdn.net/hellogv/ ,引用必须注明出处! 近期穿戴设备发展得非常火.把相关技术也带旺了,当中一项是BLE(Bluetooth Low Energy).B ...
- 高性能MySql进化论【转】
高性能MySql进化论(十二):Mysql中分区表的使用总结 http://binary.duapp.com/category/sql 当数据量非常大时(表的容量到达GB或者是TB),如果仍然采用索引 ...
- BNU10805:矩形神码的
我们都知道,矩形是由两条对角线的,没错吧?(谜之声:这不是显然么!)这两条线的长度也是相等的,没错吧?(谜之声:这不废话么!)然后我们给定一条对角线的起始点和终止点的坐标,然后给定另一个对角线和他的夹 ...
- Android万能分辨率适应法
(1)获取屏幕的尺寸 WindowManager windowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE); D ...
- resin安装和配置
1 从 http://www.caucho.com/download/ 下载resin 2 检查你的linux环境,查看是否安装了 jdk1.5 或以上版本,是否安装了perl. 输入命令:Java ...
- 查看linux版本和内核信息
一.查看Linux内核版本命令(两种方法): 1.cat /proc/version [root@localhost ~]# cat /proc/versionLinux version 2.6.32 ...
- python - XML文件及其操作
xml文件也是实现不同语言或者程序之间进行数据交换的协议,它的特点是尖括号开头,尖括号结尾.使用范围就更为广泛了,tomcat resin kvm 等等,使用了大量的xml文件来进行相关配置.先来看一 ...