题意:求给定字符串的三元组(I,J,K)  使得S[i..j] 和 S[j+1..k] 都是回文串。求所有满足条件的三元组 ∑(i*k)

题解:求出以j为结尾的回文串起始位置的和记为lv[j],和以j+1为开始的回文串末位置的和rv[j+1]

答案就是∑[j:1-n](lv[j] * rv[j+1])

因为……

(a+b+c....)*(x+y+z.....) = a*x + a*y + a*z + ....

看了题解之后才恍然大悟ˊ_>ˋ有多蠢

然后就是自己写的代码

一直wa,以为哪里没有取模,瞪了一个小时,发现,哦,有一个除法,÷2,应该算逆元

天啦噜。。。

看到很多人分了奇偶,我也没想那么多,感觉是一样的,可能效率差一些吧……

我的想法是对于每一个i,它所能到达的地方就是,i+mp[i](manacher中数组),那么对于所有它能到达的位置,设为j,j所对应的起始位置就是i*2-j,于是每次只要把所能到达的点加i,记为rv[],也就是rv[j]+i, 每个点所有前面点的贡献值就是rv[j]*2-j*ti(所能到达j点的次数)

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define ll long long
using namespace std;
const int N = ;
const ll MOD = 1000000007LL;
const ll inv = ;
char str[N];
char ma[N];
int mp[N]; ll ti[N], lv[N], rv[N]; int Manacher()
{
int len = strlen(str);
int l = ;
ma[l++] = '$';
ma[l++] = '#';
for (int i = ; i < len ; i++) {
ma[l++] = str[i];
ma[l++] = '#';
}
ma[l] = ;
int mx = ,id = ;
for (int i = ; i < l ; i++) {
mp[i] = mx > i ? min(mp[ * id - i], mx - i) : ;
while (ma[i + mp[i]] == ma[i - mp[i]]) mp[i]++;
if (i + mp[i] > mx) {
mx = i + mp[i];
id = i;
}
}
return l;
} inline void up(ll &x, ll y)
{
x += y;
if (x >= MOD) x -= MOD;
if (x < ) x += MOD;
} ll solve()
{
int l = Manacher();
memset(lv, , sizeof lv);
memset(ti, , sizeof ti);
for (int i = ; i < l; ++i) {
up(lv[i], i);
up(lv[i+mp[i]], -i);
ti[i]++;
ti[i+mp[i]]--;
}
for (int i = ; i < l; ++i) {
up(lv[i], lv[i-]);
up(ti[i], ti[i-]);
} for (int i = ; i < l; ++i) {
lv[i] = ((lv[i] * % MOD - ti[i] * i % MOD) % MOD + MOD) % MOD;
}
memset(rv, , sizeof rv);
memset(ti, , sizeof ti);
for (int i = l-; i > ; --i) {
up(rv[i], i);
up(rv[i-mp[i]], -i);
ti[i]++;
ti[i-mp[i]]--;
}
for (int i = l-; i > ; --i) {
up(rv[i], rv[i+]);
up(ti[i], ti[i+]);
}
for (int i = l-; i > ; --i) {
rv[i] = ((rv[i] * % MOD - ti[i] * i % MOD) + MOD) % MOD;
}
ll ans = ;
for (int i = ; i < l; i += ) {
ans = (ans + (lv[i] * inv % MOD) * (rv[i+] * inv % MOD) % MOD) % MOD;
}
return ans;
} int main()
{
//freopen("in", "r", stdin);
while (~scanf("%s",str)) {
cout << solve() << endl;
}
return ;
}

hdu5785--Interesting(manacher)的更多相关文章

  1. 多校1005 HDU5785 Interesting (manacher)

    // 多校1005 HDU5785 Interesting // 题意:给你一个串,求相邻两个回文串左边端点*右边端点的和 // 思路:马拉车算出最长回文半径,求一个前缀和,既得到每个点对答案的贡献. ...

  2. HDU5785 Interesting(Manacher + 延迟标记)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5785 Description Alice get a string S. She think ...

  3. 【HDU5785】Interesting [Manacher]

    Interesting Time Limit: 30 Sec  Memory Limit: 256 MB[Submit][Status][Discuss] Description Input Outp ...

  4. HDU-5785 Interesting(Manacher算法+区间处理)

    题目大意:给一个字符串,求所有相邻两回文子串的外侧下标之积的和 题目分析:另L[i]为所有以 i 为右端点的回文字串的左端点之和,同理,另R[i]表示所有以 i 为左端点的回文子串的右端点之和.显然, ...

  5. Interesting (manacher + 前缀和处理)

    题意:相邻的两端回文串的价值为两个回文串总的区间左端点 × 区间右端点.然后计算目标串中所有该情况的总和. 思路:首先用manacher求出所有中心点的最大半径,然后我们知道对于左区间我们把贡献记录在 ...

  6. HDU 5785 Interesting manacher + 延迟标记

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

  7. HDU5785 manacher+差分数组

    用manacher算法O(n)求出所有的回文半径.有了回文半径后,就可以求出L[i]表示以i结尾的回文串的起始位置的和R[i]表示以i起始的回文串的结尾位置的和,然后就可以求出答案了,这里要注意奇偶长 ...

  8. HDU3068 回文串 Manacher算法

    好久没有刷题了,虽然参加过ACM,但是始终没有融会贯通,没有学个彻底.我干啥都是半吊子,一瓶子不满半瓶子晃荡. 就连简单的Manacher算法我也没有刷过,常常为岁月蹉跎而感到后悔. 问题描述 给定一 ...

  9. manacher算法专题

    一.模板 算法解析:http://www.felix021.com/blog/read.php?2040 *主要用来解决一个字符串中最长回文串的长度,在O(n)时间内,线性复杂度下,求出以每个字符串为 ...

  10. BZOJ2342 Manacher + set

    题一:别人介绍的一道题,题意是给出一个序列,我们要求出一段最常的连续子序列,满足:该子序列能够被平分为三段,第一段和第二段形成回文串,第二段和第三段形成回文串. 题二:BZOJ2342和这题非常的相似 ...

随机推荐

  1. Eclipse 安装FindBugs插件

    FindBugs 是由马里兰大学提供的一款开源 Java静态代码分析工具.FindBugs通过检查类文件或 JAR文件,将字节码与一组缺陷模式进行对比从而发现代码缺陷,完成静态代码分析.FindBug ...

  2. http://blog.csdn.net/xyang81/article/details/7292380

    http://blog.csdn.net/xyang81/article/details/7292380

  3. 解决浮层弹出如何加上datepicker,并且浮动在上面

    最近在做一个弹出层上弹出的对话框中能弹出一个截止时间的选择框,这个选择框使用datepicker来做. 效果大致是这样的: 但是在做的时候,遇到一个问题,datepicker在弹出层的时候,时间选择框 ...

  4. P143、面试题25:二叉树中和为某一值的路径

    题目:输入一棵二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径.从树的根结点开始往下一直到叶结点所经过的结点形成一条路径.二叉树结点的定义如下:struct BinaryTreeNode ...

  5. java synchronized wait

    在多个线程要互斥访问数据,但线程间需要同步时——例如任务分多个阶段,特定线程负责特定阶段的情况,经常合作使用synchronized 和 wait() /** * * 计算输出其他线程锁计算的数据 * ...

  6. 游戏中VIP会员模块的简单实现

    哈哈  今天周末有时间,再整理一篇博文上来,虽然已经不做游戏老长时间了,但还是要把以前做过的东西总结一下,借此可以回顾以前的东西,也可以分享给大家. 今天说一下游戏中VIP会员模块的实现思路.每款游戏 ...

  7. 优化tomcat——jvm

    Tomcat 的启动参数位于tomcat的安装目录\bin目录下,如果你是Linux操作系统就是catalina.sh文件,如果你是Windows操作系统那么你需要改动的就是catalina.bat文 ...

  8. 武汉北大青鸟解读2016年10大IT热门岗位

    武汉北大青鸟解读2016年10大IT热门岗位 2016年1月5日 13:37 北大青鸟 这是IT从业者的辉煌时代,IT行业的失业率正处在历史的低点,而且有的岗位——例如网络和安全工程师以及软件开发人员 ...

  9. 数论/the first wave

    线性筛素数(原来我之前学的不是线性的啊... void getprime(){ rep(i,2,nmax){ if(!vis[i]) prime[++prime[0]]=i; for(int j=1; ...

  10. BZOJ3175: [Tjoi2013]攻击装置

    题解: 最大点独立集...好像水过头了... 不过发现我二分图好像忘完了!!! 代码: #include<cstdio> #include<cstdlib> #include& ...