题目大意:给一个字符串,求所有相邻两回文子串的外侧下标之积的和

题目分析:另L[i]为所有以 i 为右端点的回文字串的左端点之和,同理,另R[i]表示所有以 i 为左端点的回文子串的右端点之和。显然,答案为sigma(L[i]*R[i+1]) 其中,1<=i<length(字符串)。求出L和R是关键。先用manacher算法处理出p数组,然后再求出L和R。求L和R的思想(非常巧妙)跟树状数组求区间和的思想差不多。不过,这道题如果用树状数组或线段树的话会超时。

参考代码:

# include<iostream>
# include<cstdio>
# include<cstring>
# include<algorithm>
using namespace std;
# define LL long long const int mod=1000000007;
const int N=1000000; char str[N+5];
char m[(N<<1)+5];
int p[(N<<1)+5]; LL addtag[2][N+5];
LL subtag[2][N+5];
LL addcnt[2][N+5];
LL subcnt[2][N+5];
LL val[2][N+5]; void manacher(char *ch)
{
int len=strlen(ch+1);
int cnt=0;
m[cnt++]='@';
m[cnt++]='#';
for(int i=1;i<=len;++i){
m[cnt++]=ch[i];
m[cnt++]='#';
}
m[cnt]='\0';
int id,mx=0;
for(int i=1;i<cnt;++i){
if(mx>i) p[i]=min(mx-i,p[2*id-i]);
else p[i]=1;
while(m[i-p[i]]==m[i+p[i]]) ++p[i];
if(i+p[i]>mx){
mx=i+p[i];
id=i;
}
}
} void update(int id,int l,int r,int a)
{
addtag[id][l]+=a;
addtag[id][l]%=mod;
++addcnt[id][l];
subtag[id][r+1]+=a-r+l;
subtag[id][r+1]%=mod;
++subcnt[id][r];
} void pushDown(int n)
{
for(int i=1;i<=n;++i){
if(addcnt[0][i]){
val[0][i]+=addtag[0][i];
val[0][i]%=mod;
addtag[0][i+1]+=addtag[0][i]-addcnt[0][i];
addtag[0][i+1]%=mod;
addcnt[0][i+1]+=addcnt[0][i];
}
if(subcnt[0][i]){
val[0][i]-=subtag[0][i];
val[0][i]%=mod;
subtag[0][i+1]+=subtag[0][i]-subcnt[0][i];
subtag[0][i+1]%=mod;
subcnt[0][i+1]+=subcnt[0][i];
}
if(addcnt[1][i]){
val[1][i]+=addtag[1][i];
val[1][i]%=mod;
addtag[1][i+1]+=addtag[1][i]-addcnt[1][i];
addtag[1][i+1]%=mod;
addcnt[1][i+1]+=addcnt[1][i];
}
if(subcnt[1][i]){
val[1][i]-=subtag[1][i];
val[1][i]%=mod;
subtag[1][i+1]+=subtag[1][i]-subcnt[1][i];
subtag[1][i+1]%=mod;
subcnt[1][i+1]+=subcnt[1][i];
}
}
} int main()
{
while(~scanf("%s",str+1))
{
manacher(str);
memset(val,0,sizeof(val));
memset(addtag,0,sizeof(addtag));
memset(subtag,0,sizeof(subtag));
memset(addcnt,0,sizeof(addcnt));
memset(subcnt,0,sizeof(subcnt));
for(int i=1;m[i];++i){
if(i&1){
if(p[i]==1) continue;
update(0,i/2+1,i/2+p[i]/2,i/2);
update(1,i/2-p[i]/2+1,i/2,i/2+p[i]/2);
}else{
int id=i/2;
int l=(p[i]-1)/2;
update(0,id,id+l,id);
update(1,id-l,id,id+l);
}
}
int n=strlen(str+1);
pushDown(n);
LL ans=0;
for(int i=1;i<n;++i){
ans+=val[0][i]*val[1][i+1];
ans%=mod;
}
while(ans<0) ans+=mod;
printf("%lld\n",ans);
}
return 0;
}

  

HDU-5785 Interesting(Manacher算法+区间处理)的更多相关文章

  1. HDU 5785 Interesting manacher + 延迟标记

    题意:给你一个串,若里面有两个相邻的没有交集的回文串的话,设为S[i...j] 和 S[j+1...k],对答案的贡献是i*k,就是左端点的值乘上右端点的值. 首先,如果s[x1....j].s[x2 ...

  2. HDU 5785 Interesting

    题目: 大概说给一个字符串,找到其所有子串[i...k]满足它是由两个回文串拼成的,求Σi*k. 分析: 用val[1][i]表示以i结尾的回文串的起始位置的和val[0][i]表示以i起始的回文串的 ...

  3. hdu 3068 最长回文 (Manacher算法求最长回文串)

    参考博客:Manacher算法--O(n)回文子串算法 - xuanflyer - 博客频道 - CSDN.NET 从队友那里听来的一个算法,O(N)求得每个中心延伸的回文长度.这个算法好像比较偏门, ...

  4. Manacher 算法(hdu 3068 && hdu 3294)

    今天打算补前晚 BC 的第二题,发现要用到能在 O(n) 时间求最大回文子串长度的 Manacher 算法,第一次听,于是便去百度了下,看了大半天,总算能看懂了其思想,至于他给出的代码模板我没能完全看 ...

  5. hdu 3068 最长回文 manacher算法(视频)

    感悟: 首先我要Orz一下qsc,我在网上很难找到关于acm的教学视频,但偶然发现了这个,感觉做的很好,链接:戳戳戳 感觉这种花费自己时间去教别人的人真的很伟大. manacher算法把所有的回文都变 ...

  6. HDU 5371(2015多校7)-Hotaru&#39;s problem(Manacher算法求回文串)

    题目地址:HDU 5371 题意:给你一个具有n个元素的整数序列,问你是否存在这样一个子序列.该子序列分为三部分,第一部分与第三部分同样,第一部分与第二部分对称.假设存在求最长的符合这样的条件的序列. ...

  7. HDU 3068:最长回文(Manacher算法)

    http://acm.hdu.edu.cn/showproblem.php?pid=3068 最长回文 Problem Description   给出一个只由小写英文字符a,b,c...y,z组成的 ...

  8. HDU 3068 最长回文 Manacher算法

    Manacher算法是个解决Palindrome问题的O(n)算法,能够说是个超级算法了,秒杀其它一切Palindrome解决方式,包含复杂的后缀数组. 网上非常多解释,最好的解析文章当然是Leetc ...

  9. hdu 3613"Best Reward"(Manacher算法)

    传送门 题意: 国王为了犒劳立下战功的大将军Li,决定奖给Li一串项链,这个项链一共包含26中珠子"a~z",每种珠子都有 相应的价值(-100~100),当某个项链可以构成回文时 ...

随机推荐

  1. Ohlàlà

    Chap 1数数字 un 1 deux 2 trois 3 quatre 4 cinq 5 six 6 sept 7 huit 8 neuf 9 dix 10   Chap 2 讲地名 Paris 巴 ...

  2. JS获取上传文件的名称、格式、大小

    <input id="File1" type="file" onchange="checkFile(this)" /> 方式一) ...

  3. AJAX笔记

    浏览器脚本——AJAX AJAX =  异步的 JavaScript 和 XML(Asynchronous JavaScript and XML). 是一种新的技术,它可以创建更好.更快且交互性更强的 ...

  4. 《CheckboxDemo.java》

    import java.awt.*; import java.applet.Applet; public class CheckboxDemo extends Applet { String Uni[ ...

  5. poj2392 多重背包

    //Accepted 868 KB 188 ms //多重背包 #include <cstdio> #include <cstring> #include <iostre ...

  6. VM虚拟机中Ubuntu无法连接网络

    之前Ubuntu是可以上网的,但是今天打开后发现上不了网了,经过一番折腾,弄好了,记录下. 方案一:将网络连接设置为自定义NAT VM ->设置-> 硬件->网络适配器 这么已修改就 ...

  7. 利用strut2标签自动生成form前端验证代码

    利用strut2标签自动生成form前端验证代码,使用到的技术有1.struts2标签,如<s:form> <s:textfieled>2.struts2读取*Validati ...

  8. Sql Server REPLACE函数的使用;SQL中 patindex函数的用法

    Sql Server REPLACE函数的使用 REPLACE用第三个表达式替换第一个字符串表达式中出现的所有第二个给定字符串表达式. 语法REPLACE ( ''string_replace1'' ...

  9. 实现:编辑短信,按power键锁屏后,再点亮屏幕,进入的还是编辑短信界面,按返回键才会进入解锁界面。

    描述:在编辑短信界面按电源键锁屏后,重新按电源键点亮屏幕,并没有进入到锁屏界面而是在编辑短信界面,此时短信界面悬浮与锁屏界面之上,这时按返回键关闭编辑短信界面,回到锁屏界面,是如何实现的呢,只需要在需 ...

  10. Unity3D ShaderLab 车辆喷漆光照模型实战

    这一篇,我们来创建一个车辆喷漆的光照模型.首先就是准备场景,新建Shader & Material. 过程比较简单,直接看完成的代码吧: Shader "91YGame/CarOut ...