「Codechef April Lunchtime 2015」Palindromeness

解题思路 :

考虑对于回文子串 \(s\) 贡献的定义:

\[value_s = [\ s[1,\lfloor \frac{|s|}{2}\rfloor]\text{ is palindrome}]\times value_{s[1,\lfloor \frac{|s|}{2}\rfloor]} + 1
\]

也就是说对于每一个回文子串,只需要判断其前一半的字符是不是回文串并得到贡献即可。

于是建出回文树,可以通过跳 \(fail\) 得到其所有回文前缀,用倍增找到第一个长度小于等于一半的回文前缀,判断其长度是否恰好是一半并继承贡献。

令 \(size_u\) 表示回文树上一个节点所代表的回文串的 \(right\) 集合大小,则

\[Ans =\sum_{u \text{ in pam}} size_u \times value_u
\]

总复杂度 \(O(|s|log|s|)\) 。

/*program by mangoyang*/
#include<bits/stdc++.h>
#define inf ((int)(1e9))
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
typedef long long ll;
using namespace std;
template <class T>
inline void read(T &x){
int f = 0, ch = 0; x = 0;
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = 1;
for(; isdigit(ch); ch = getchar()) x = x * 10 + ch - 48;
if(f) x = -x;
}
const int N = 200005;
char s[N];
namespace PAM{
ll ans;
int ch[N][26], sz[N], fa[N], len[N], f[N][21], val[N], size, tail;
inline int newnode(int x){ return len[++size] = x, size; }
inline void init(){
memset(ch, 0, sizeof(ch));
memset(fa, 0, sizeof(fa));
memset(sz, 0, sizeof(sz));
len[1] = -1, fa[0] = 1, size = tail = 1, ans = 0;
}
inline void pushback(int pos){
int c = s[pos] - 'a', p = tail;
while(s[pos-len[p]-1] != s[pos]) p = fa[p];
if(ch[p][c]) return (void) (sz[tail=ch[p][c]]++);
int np = newnode(len[p] + 2), u = fa[p];
while(s[pos-len[u]-1] != s[pos]) u = fa[u];
fa[np] = ch[u][c], sz[tail=ch[p][c]=np]++;
}
inline void solve(){
for(int i = 1; i <= size; i++) f[i][0] = fa[i];
for(int j = 1; j <= 20; j++)
for(int i = 1; i <= size; i++)
f[i][j] = f[f[i][j-1]][j-1];
for(int i = 2; i <= size; i++){
val[i] = 1; int x = i;
for(int j = 20; ~j; j--)
if(len[f[x][j]] >= len[i] / 2) x = f[x][j];
if(len[x] == len[i] / 2) val[i] += val[x];
}
for(int i = size; i > 2; i--) sz[fa[i]] += sz[i];
for(int i = 2; i <= size; i++) ans += 1ll * val[i] * sz[i];
cout << ans << endl;
}
}
int main(){
int T; read(T);
while(T--){
scanf("%s", s + 1); int n = strlen(s + 1);
PAM::init();
for(int i = 1; i <= n; i++) PAM::pushback(i);
PAM::solve();
}
return 0;
}

「Codechef April Lunchtime 2015」Palindromeness的更多相关文章

  1. 「清华集训2015」V

    「清华集训2015」V 题目大意: 你有一个序列,你需要支持区间加一个数并对 \(0\) 取 \(\max\),区间赋值,查询单点的值以及单点历史最大值. 解题思路: 观察发现,每一种修改操作都可以用 ...

  2. 众安「尊享e生」果真牛的不可一世么?

    近日,具有互联网基因的.亏损大户(成立三年基本没盈利,今年二季度末亏损近4亿,你能指望它多厉害?).财产险公司—众安推出“尊享e生”中高端医疗保险(财险公司经营中高端医疗真的很厉害?真的是中高端医疗险 ...

  3. C#下实现的K-Means优化[1]-「离群点检测」

    资源下载 #本文PDF版下载 C#下实现的K-Means优化[1]-「离群点检测」 前言 在上一篇博文中,我和大家分享了「C # 下实现的多维基础K-MEANS聚类」的[C#下实现的基础K-MEANS ...

  4. XCActionBar 「Xcode 中的 Alfred」

    下载地址:https://github.com/pdcgomes/XCActionBar 基本命令: (1)「command+shift+8」或者双击「command」键可以打开「动作输入框窗口」 ( ...

  5. Git 执行 「fork 出来的仓库」和「最新版本的原仓库」内容同步更新

    当我们在 GitHub 上 fork 出一个仓库后,如果原仓库更新了,此时怎样才能保证我们 fork 出来的仓库和原仓库内容一致呢?我们一般关注的是仓库的 master(主干分支)的内容,通过以下步骤 ...

  6. 翻译「C++ Rvalue References Explained」C++右值引用详解 Part1:概述

    本文系对「C++ Rvalue References Explained」 该文的翻译,原文作者:Thomas Becker. 该文较详细的解释了C++11右值引用的作用和出现的意义,也同时被Scot ...

  7. 苹果搜索广告后台大揭秘,最全最细致详解,手把手设置教程「后附官方视频」-b

    WWDC2016 搜索广告分会视频和 PPT 发布了,ASO100 带开发者第一时间了解 Search Ads 后台设置(文末有原声视频). 首先介绍一下搜索广告的模式和竞价规则 广告模式为 CPT( ...

  8. 被「李笑来老师」拉黑之「JavaScript微博自动转发的脚本」

    故事的背景如下图,李笑来 老师于10月19日在 知乎Live 开设 一小时建立终生受用的阅读操作系统 的讲座,他老人家看到大家伙报名踊跃,便在微博上发起了一个 猜数量赢取iPhone7 的活动. 因为 ...

  9. iOS模式详解—「runtime面试、工作」看我就 🐒 了 ^_^.

    Write in the first[写在最前] 对于从事 iOS 开发人员来说,当提到 ** runtime时,我想都可以说出来 「runtime 运行时」和基本使用的方法.相信很多开发者跟我当初一 ...

随机推荐

  1. BZOJ做题记录[0512~?]

    觉得做一道开一篇真不好...好多想找的东西都被刷下去了... 至于?的日期究竟到什么时候...还是看心情...但是估计不会超过七天吧 最后更新时间:05/19 10:42 [05/14 10:56]我 ...

  2. 【BZOJ】2553: [BeiJing2011]禁忌 AC自动机+期望+矩阵快速幂

    [题意]给定n个禁忌字符串和字符集大小alphabet,保证所有字符在集合内.一个字符串的禁忌伤害定义为分割能匹配到最多的禁忌字符串数量(一个可以匹配多次),求由字符集构成的长度为Len的字符串的期望 ...

  3. text-align: justify;不能均匀分布问题

    本文地址:http://www.cnblogs.com/veinyin/p/7617610.html  对于text-align来说,一般我们都是使用居中这个属性值,突然今天需要达到这样一个效果: 对 ...

  4. 数据库-Core Data

    技术博客http://www.cnblogs.com/ChenYilong/ 新浪微博http://weibo.com/luohanchenyilong  数据库-Core Data  技术博客htt ...

  5. CodeForces - 999C

    You are given a string ss consisting of nn lowercase Latin letters. Polycarp wants to remove exactly ...

  6. npm的常用命令

    npm install <name>安装nodejs的依赖包 例如npm install express 就会默认安装express的最新版本,也可以通过在后面加版本号的方式安装指定版本, ...

  7. 南邮综合题writeup

    http://teamxlc.sinaapp.com/web3/b0b0ad119f425408fc3d45253137d33d/index.php fuckjs直接console得到地址 http: ...

  8. Java network programming-guessing game

    猜数字游戏 游戏的规则如下: 当客户端第一次连接到服务器端时,服务器端生产一个[0,50]之间的随机数字,然后客户端输入数字来猜该数字,每次客户端输入数字以后,发送给服务器端,服务器端判断该客户端发送 ...

  9. ssh修改端口号并进行远程访问

    ssh的访问如果都利用22端口,则会容易被攻击,修改一个端口号可增强一定的安全性 1. 修改配置文件sshd_config里端口号 [root@test ~]# vi /etc/ssh/sshd_co ...

  10. JavaScript 去字符串空格

    JavaScript 去字符串空格 (利用正则) # str为要去除空格的字符串: # 去除所有空格: str = str.replace(/\s+/g,""); # 去除两头空格 ...