【dtoj#1029】第二饭堂

0 篇文章 0 订阅

传送门

题目描述

由于一饭班长表示各种鸭梨,美丽的纪中决定历史性地启用第二饭堂。而部分领导觉得,二饭依山傍水,环境优美,未免有不和谐的事情(你懂的)发生,决定到二饭巡视同学们用餐时的就座情况。
为了应付这一情况,同学们决定联合起来“布阵”。
方便起见,同学们已经把座位情况抽象成一个长度为 n n n 的仅含数字及字母的字符串,他们想请你帮忙算算这个字符串的和谐程度。
已知一个字符串被称为 k − k- k回文串的充要条件是它自身是回文串,并且它长为 n / 2 n/2 n/2(下取整)的前缀和后缀是 ( k − 1 ) − (k-1)- (k1)回文串。根据定义,任意字符串(包括空串)都是 0 − 0- 0回文串。
一个字符串的回文度数就是这个字符串的k的最大值。
而对于一个给定的字符串,它的和谐程度就是其所有前缀的回文度数之和。
你的任务就是算出这个和谐程度具体是多少。

输入格式

一行一个仅包含数字和字母的字符串。

输出格式

一行一个整数表示这个字符串的和谐程度。

样例输入
abacaba
样例输出
6
数据范围与提示

对于 30 % 30\% 30% 的数据字符串长度不超过 1000 1000 1000
对于 70 % 70\% 70% 的数据字符串长度不超过 100000 100000 100000
对于 100 % 100\% 100% 的数据字符串长度不超过 5000000 5000000 5000000

题解

题意我花了点时间理解,大概可以概括为求这个字符串包含了多少“层”回文串k就是多少,但是这道题完全没必要理解题意(甚至理解了反而可能会想偏),可以直接照题干按部就班dp(逃
在每一次输入操作后求出这个串正向和反向的哈希值,如果相等就是回文串,然后进行dp即可。
代码:

#include<iostream>
#include<cstdio>
using namespace std;
int ans,w=1,Lhash,Rhash,F[5000010],n;
const int seed=100007;
char ch;
int main(){
	while((ch=getchar())!='\n'){
		n++;
		Lhash=Lhash+(ch-96)*w;
		Rhash=Rhash*seed+(ch-96);
		w*=seed;
		if(Lhash==Rhash) F[n]=F[n>>1]+1;
		ans+=F[n];
	}
	cout<<ans<<endl;
	return 0;
}

Thanks!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值