【BZOJ2803】[Poi2012]Prefixuffix 结论题

【BZOJ2803】[Poi2012]Prefixuffix

Description

对于两个串S1、S2,如果能够将S1的一个后缀移动到开头后变成S2,就称S1和S2循环相同。例如串ababba和串abbaab是循环相同的。
给出一个长度为n的串S,求满足下面条件的最大的L:
1. L<=n/2
2. S的L前缀和S的L后缀是循环相同的。

Input

第一行一个正整数n (n<=1,000,000)。第二行n个小写英文字母,表示串S。

Output

一个整数,表示最大的L。

Sample Input

15
ababbabababbaab

Sample Output

6

题解:一个不容易发现但是很好证的结论:令f[i]表示最长的一段区间,使得[i+1,i+f[i]+1]=[n-i-f[i],n-i-1],然后hash搞一搞

但是此题卡hash,于是%了其他大神的hash代码~

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
typedef long long ll;
const int maxn=1000010;
const ll mod=1000000009;
ll seed[maxn],s[maxn],hash[maxn];
int n,ans;
char str[maxn];
ll gethash(int a,int b)
{
	return (hash[b]-hash[a-1]*seed[b-a+1]%mod+mod)%mod;
}
int main()
{
	seed[1]=1000000007,seed[0]=1;
	scanf("%d%s",&n,str+1);
	int i,j;
	for(i=1;i<=n;i++)
		seed[i]=seed[i-1]*seed[1]%mod,s[i]=(s[i-1]+str[i])%mod,hash[i]=(hash[i-1]*seed[1]+str[i])%mod;
	for(i=n/2,j=0;i>0;i--,j=min(j+2,n/2-i))
	{
		if(s[i]==s[n]-s[n-i]&&gethash(1,i)==gethash(n-i+1,n))
		for(;j>=0;j--)
		{
			if(s[i+j]-s[i]==s[n-i]-s[n-i-j]&&gethash(i+1,i+j)==gethash(n-i-j+1,n-i))
			{
				ans=max(ans,i+j);
				break;
			}
		}
	}
	printf("%d",ans);
	return 0;
}
时间: 2024-10-08 15:03:29

【BZOJ2803】[Poi2012]Prefixuffix 结论题的相关文章

【bzoj2079】[Poi2010]Guilds 构造结论题

题目描述 Zy皇帝面临一个严峻的问题,两个互相抵触的贸易团体,YYD工会和FSR工会,他们在同一时间请求在王国各个城市开办自己的办事处.这里有n个城市,其中有一些以双向马路相连,这两个工会要求每个城市应该做到: 1:有这个工会的办事处或 2:和另外一个符合1条件的城市有马路直接相连.(也就是每个城市必须是YYD的公会,但是又和FSR的公会的城市相连,或者是FSR的,和YYD的城市相连,或者和两个工会的城市相连)但是Zy怀疑不正当的竞争,他担心一个城市有两个工会的办事处,(就是说一个城市不能有两个

[codevs5578][咸鱼]tarjan/结论题

5578 咸鱼 时间限制: 1 s 空间限制: 128000 KB 题目描述 Description 在广袤的正方形土地上有n条水平的河流和m条垂直的河流,发达的咸鱼家族在m*n个河流交叉点都建立了城市.然而,由于河流有单一的流向,而咸鱼们却没有发达的下体,所以只能顺流而下.两两河流之间的流向互不影响. 现在,咸鱼冒险家Sorey决定出发去看看这个世界,但是Sorey担心自己可能被困在某个城市而无法回归自己的家乡.于是Sorey夜观天象,搞清楚了每条河的流向,他想请你帮他判断他的旅途是否会顺利.

【BZOJ4378】[POI2015]Logistyka【树状数组】【结论题】

[题目链接] 题解: 首先得有一个结论:设个数大于s的数字有k个(如果k大于c,显然是TAK.这里讨论k <= c),那么如果个数小于s的数字和不小于(c - k) * s,那么一定有解. 并不会证明... 用树状数组记录一下数字的个数以及数字的数字和,然后判断就可以了. 复杂度: 时间复杂度:O(mlogm),空间复杂度:O(m). 1A. GET: 结论题... /* Telekinetic Forest Guard */ #include <cstdio> #include <

[bzoj1369][Baltic2003]Gem_树形dp_结论题

Gem bzoj-1369 Baltic-2003 题目大意:给你一棵树,让你往节点上添自然数,使得任意相邻节点的数不同且使得权值最小. 注释:n为结点个数,$1\le n\le 10^3$. 想法:呵呵,学长一直在骂结论题,我一直觉得没啥.. ... 知道tm碰见这玩意儿,卧槽?! 树上相邻节点不同色,颜色个数最小值至多为logn. 最后,附上丑陋的代码... ... #include <iostream> #include <cstring> #include <cstd

沙雕打表结论题

没有链接 描述: 给p,q,求a^2+b^2 = p*q解的个数,p,q是素数 沙雕打表结论题 然后怼了3h吼爆零 题解 首先这是个结论题 然后这是证明 代码 #include <stdio.h> #include <algorithm> using namespace std; int p , q; int ans; void work () { scanf ( "%d%d" , &p , &q ); if ( p > q ) swap

codeforces 1269D. Domino for Young (二分图证明/结论题)

链接:https://codeforces.com/contest/1269/problem/D 题意:给一个不规则的网格,在上面放置多米诺骨牌,多米诺骨牌长度要么是1x2,要么是2x1大小,问最多放置多米诺骨牌的数量. 思路:首先这是一个结论题,对每个方格进行染色,一个方格染黑色,周围邻近的就染白色,答案就是黑色方格数量和白色方格数量的最小值.这个结论可以用二分图进行证明:把问题抽象成最大二分图匹配,每两个点之间连一条边.一个格子和周围格子连一条边,如果一个格子周围的还没被匹配,那么匹配数+1

[BZOJ1016][JSOI2008]最小生成树计数(结论题)

题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1016 分析: 首先有个性质:如果边集E.E'都可以表示一个图G的最小生成树(当然E和E’的元素个数肯定一样),那么某确定权值的边在E中出现的次数==在E‘中出现的次数 简单证明一下: 按照Kruskal算法的流程来想,首先我们知道Kruskal求一个最小生成树是正确的,那么不同的最小生成树会怎么产生呢?当然是Kruskal选择权值相同的边的顺序,很有可能选择权值相同边的顺序不同导致后

hdu Pocket Cube(结论题)

题意:给出一个二阶魔方的状态,求是否能还原: 参考:http://blog.csdn.net/squee_spoon/article/details/46990969(郑大cuber) 思路:一个二阶魔方的相邻角块交换情况如下图: 将终状态的每个方块赋值,旋转后权值不会变化: 考虑题干中黄白为对立面,将其权值赋0: 顺时针赋1,否则-1: 若黄白块的权值和被三整除,可还原:否则不可还原: #include<cstdio> #include<cstring> #include<

BZOJ 2803 Poi2012 Prefixuffix Hash

题目大意:给定一个字符串S,求一个最长的L(L*2<=n),使S长度为L的前缀和长度为L的后缀循环同构 一开始我的想法是枚举L,判断长度为L的前缀和长度为L的后缀的所有循环同构的哈希值之和是否相等 但是很快我发现这做法是扯淡- - 因为一个字符串所有循环同构的哈希值之和等于这个字符串所有字符ASCII码之和乘上(BASE^len+BASE^(len-1)+...+BASE^2+BASE+1) 然后我在想能不能考虑修改一下哈希函数呢? 比如给每个字符一个BASE,定义一个字符串的哈希值为以字符串开