2017.10.6 国庆清北 D6T3 字符串
题目描述
如果把一个字符串从头到尾翻转后和原字符串相等,我们称之为回文串,比如“aabaa”、“())(”、“2017102”。
如果一个字符串存在两个出现过的字母出现的次数相等,我们称之为好
的字符串。
现在给一个由小写字母组成的字符串,问在这个字符串的所有连续的串
中,好的回文串有多少个。(两个相同的回文串出现在不同位置算多次)。
输入输出格式
输入格式:
一行一个小写字母组成的字符串。
输出格式:
一行一个整数,表示答案。
输入输出样例
abcbaabcba
6
【样例解释】
abcba s[1..5] a,b 出现次数相等
baab s[4..7] a,b 出现次数相等
cbaabc s[3..8] a,b 出现次数相等
bcbaabcb s[2..9] a,c 出现次数相等
abcbaabcba s[1..10] a,b 出现次数相等
abcba s[6..10] a,b 出现次数相等
说明
len 表示字符串长度。
对于30% 的数据, len <=10^2。
对于60% 的数据, len <= 10^3。
对于100% 的数据,1 <= len <= 10^4。
/*
我们发现回文串是可以二分的
比如:bbbabcbaabcba 我们以第1个c为中心,发现回文半径是3,大于3一定不是回文串。当回文串长度为偶数的时候,我们需要特殊处理一下。
现在有一个结论:本质不同的回文串个数只有O(N)个
本质不同:字符串本身是不同的。
每一次处理完回文串,我们要把他的hash值记录下来。
*/ #include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
using namespace std; typedef unsigned long long ULL;
typedef long long LL; char s[];
ULL h[],rh[],pw[];
int L; ULL hs(int l,int r)
{
return h[r]-h[l-]*pw[r-l+];
}
ULL rhs(int l,int r)
{
return rh[l]-rh[r+]*pw[r-l+];
}
struct N
{
int a[];
bool ok(){
int b[];
for(int i=;i<;i++) b[i]=a[i];
sort(b,b+);
for(int i=;i<;i++)
{
if(b[i]>&& b[i] == b[i+]) return true;
}
return false;
}
void clear()
{
memset(a,,sizeof a);
}
};
LL ans=;
map<ULL,LL> num;
map<ULL,N> A;
void solve_odd() //奇数
{
for(int i=;i<=L;i++)
{
int l=,r=min(i,L-i+)+;
while(r-l>)
{
int mid=(l+r)/;
if(hs(i-mid+,i+mid-)==rhs(i-mid+,i+mid-)) l=mid;
else r=mid;
}
int p=l;
int tmp=p;
while(tmp>=&&num.find(hs(i-tmp+,i+tmp-))==num.end()) tmp--;
LL sum=;
N st;
st.clear();
if(tmp>=)
{
sum=num[hs(i-tmp+,i+tmp-)];
st=A[hs(i-tmp+,i+tmp-)];
}
while(tmp<p)
{
st.a[s[i+tmp]-'a']+=(tmp==?:);
if(st.ok()) sum++;
num[hs(i-tmp,i+tmp)]=sum;
A[hs(i-tmp,i+tmp)]=st;
tmp++;
}
ans+=sum;
}
}
void solve_even() //偶数
{
A.clear();
num.clear();
for(int i=;i<L;i++)
{
int l=,r=min(i,L-i)+;
while(r-l>)
{
int mid=(l+r)/;
if(hs(i-mid+,i+mid)== rhs(i-mid+,i+mid)) l=mid;
else r=mid;
}
int p=l;
int tmp=p;
while(tmp>=&&num.find(hs(i-tmp+,i+tmp))==num.end()) tmp--;
LL sum = ;
N st;
st.clear();
if(tmp>=)
{
sum=num[hs(i-tmp+,i+tmp)];
st=A[hs(i-tmp+,i+tmp)];
}
while(tmp<p)
{
st.a[s[i+tmp+]-'a']+=;
if(st.ok()) sum++;
num[hs(i-tmp,i+tmp+)]=sum;
A[hs(i-tmp,i+tmp+)]=st;
tmp++;
}
ans+=sum;
}
} int main()
{
scanf("%s",s+);
L=strlen(s+);
s[]='#';
pw[]=;
for(int i=;i<=L;i++) pw[i]=pw[i-]*; ///hash值
for(int i=;i<=L;i++) h[i]=h[i-]*+s[i];
for(int i=L;i>=;i--) rh[i]=rh[i+]*+s[i];
solve_odd();
solve_even();
printf("%lld\n",ans);
fclose(stdout);
return ;
}
2017.10.6 国庆清北 D6T3 字符串的更多相关文章
- 2017.10.1 国庆清北 D1T1 zhx的字符串题
		题目背景 2017国庆清北D1T1 题目描述 你是能看到第一题的 friends 呢. ——hja 何大爷对字符串十分有研究,于是天天出字符串题虐杀 zhx.何大爷今天为 字符串定义了新的权值计算方法 ... 
- 2017.10.3 国庆清北 D3T1 括号序列
		题目描述 LYK有一个括号序列,但这个序列不一定合法. 一个合法的括号序列如下: ()是合法的括号序列. 若A是合法的括号序列,则(A)是合法的括号序列. 若A和B分别是合法的括号序列,则AB是合法的 ... 
- 2017.10.4 国庆清北 D4T2 正方形
		题目描述 在一个10000*10000的二维平面上,有n颗糖果. LYK喜欢吃糖果!并且它给自己立了规定,一定要吃其中的至少C颗糖果! 事与愿违,LYK只被允许圈出一个正方形,它只能吃在正方形里面的糖 ... 
- 2017.10.6 国庆清北 D6T2 同余方程组
		题目描述 求关于x 的同余方程组 x%a1 = b1 x%a2 = b2 x%a3 = b3 x%a4 = b4 的大于等于0 的最小整数解. 输入输出格式 输入格式: 一行8 个整数,表示a1; b ... 
- 2017.10.6 国庆清北 D6T1 排序
		题目描述 小Z 有一个数字序列a1; a2; .... ; an,长度为n,小Z 只有一个操作:选 定p(1<p<n),然后把ap 从序列中拿出,然后再插⼊到序列中任意位置. 比如a 序列 ... 
- 2017.10.3 国庆清北 D3T3 解迷游戏
		题目描述 LYK进了一家古董店,它很想买其中的一幅画.但它带的钱不够买这幅画. 幸运的是,老板正在研究一个问题,他表示如果LYK能帮他解出这个问题的话,就把这幅画送给它. 老板有一个n*m的矩阵,他想 ... 
- 2017.10.3 国庆清北 D3T2 公交车
		题目描述 LYK在玩一个游戏. 有k群小怪兽想乘坐公交车.第i群小怪兽想从xi出发乘坐公交车到yi.但公交车的容量只有M,而且这辆公交车只会从1号点行驶到n号点. LYK想让小怪兽们尽可能的到达自己想 ... 
- 2017.10.4 国庆清北 D4T1 财富
		(其实这题是luogu P1901 发射站 原题,而且数据范围还比luogu小) 题目描述 LYK有n个小伙伴.每个小伙伴有一个身高hi. 这个游戏是这样的,LYK生活的环境是以身高为美的环境,因此在 ... 
- 2017.10.7 国庆清北 D7T1 计数
		题目描述 给出m个数a[1],a[2],…,a[m] 求1~n中有多少数不是a[1],a[2],…,a[m]的倍数. 输入输出格式 输入格式: 输入文件名为count.in. 第一行,包含两个整数:n ... 
随机推荐
- Java线程同步类容器和并发容器(四)
			同步类容器都是线程安全的,在某些场景下,需要枷锁保护符合操作,最经典ConcurrentModifiicationException,原因是当容器迭代的过程中,被并发的修改了内容. for (Iter ... 
- BUAA OO 2019 第四单元作业总结
			目录 第四单元总结 总 UML UML 类图 UML 时序图 UML 状态图 架构设计 第十三次作业 第十四次作业 课程总结 历次作业总结 架构设计 面向对象方法理解 测试方法理解与实践 改进建议 尽 ... 
- lnmp环境快速搭建及原理解析
			刚开始学习php的时候是在wamp环境下开发的,后来才接触到 lnmp 环境当时安装lnmp是按照一大长篇文档一步步的编译安装,当时是真不知道是在做什么啊!脑袋一片空白~~,只知道按照那么长的一篇文档 ... 
- Spring Boot 实战 —— MyBatis(注解版)使用方法
			原文链接: Spring Boot 实战 -- MyBatis(注解版)使用方法 简介 MyBatis 官网 是这么介绍它自己的: MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过 ... 
- 【面试突击】- Mybatis-#{}和${}的区别
			原文链接:mybatis中#{}和${}的区别 1. #将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号.如:order by #user_id#,如果传入的值是111,那么解析成sql时 ... 
- vue动态加载图片
			如果是直接动态获取完整的图片地址可以使用以下方法 <template> <img :src="url"> </template> <scr ... 
- day33-python之多线程
			1.多线程实例 # import threading # import time # # import threading import time class MyThread(threading.T ... 
- oracle 中查询当前用户可以看到的表名、表对应的所有字段 原
			转自:https://my.oschina.net/u/3783799/blog/2870207 1.oracle 查询当前用户下的表名,表注释 select t.table_name, f.comm ... 
- Java编程规范(命名规则)
			1.目的 编程规范是对编程的一种约定,主要作用是增强代码的可读性和可维护性,便于代码重用. 2.命名规则 首先要求程序中的各个要素都遵守命名规则,然后在编码中严格按照编码格式编写代码.命名规则包括以下 ... 
- Js获取url问号(View_Detail?data='+data.zjb_ID+'&'+data.D_Name)传值
			Js逻辑 View_Detail?data='+data.zjb_ID+'&'+data.D_Name <script> $(function () { var url = dec ... 
