首页 > 其他分享 >CF30E Tricky and Clever Password 题解

CF30E Tricky and Clever Password 题解

时间:2024-07-29 14:50:44浏览次数:6  
标签:Tricky Clever int 题解 void printf ch apos ans

考虑先贪心中间的回文串 \(b\),因为这即使影响了两边的字符串,也不会改变最终的总串长。所以先使用 manacher 跑出来每个位置的最长回文半径。

在考虑怎样找出最长的 \(a\) 和 \(a'\)。可以二分答案,设此时答案为 \(k\),找出的 \(b\) 串为 \(s[l\dots r]\),那么其合法的条件就是存在 \(i \in [1,l-k]\) 使得 \(lcp(s[i\dots n],rev(s)) \ge k\)。前缀查询 \(lcp\),使用 Z 函数预处理前缀 \(\max\) 即可。

代码:

#include<bits/stdc++.h>
using namespace std;
inline void rd(){}
template<typename T,typename ...U>
inline void rd(T &x,U &...args){
	char ch=getchar();
	T f=1;x=0;
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9')x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
	x*=f;rd(args...);          
} 
const int N=1e5+5;
char c[N],rv[N];
int n,p[N],z[N],zt[N],pr[N];
int ans,apos,mx=-1;
inline void manacher(){
	int now=0,mid=0;
	c[0]='~',c[n+1]='!';
	for(int i=1;i<=n;i++){
		if(i<=now)p[i]=min(p[2*mid-i],now-i+1);
		else p[i]=1;
		while(c[i+p[i]]==c[i-p[i]])++p[i];
		if(i+p[i]-1>=now)now=i+p[i]-1,mid=i;
	}
}
inline void ZAlgorithm(){
	int l=0,r=0;
	for(int i=2;i<=n;i++){
		if(i<=r)z[i]=min(z[i-l+1],r-i+1);
		else z[i]=0;
		while(i+z[i]<=n&&rv[i+z[i]]==rv[z[i]+1])++z[i];
		if(i+z[i]>r)r=i+z[i]-1,l=i;
	}
}
inline void zzz(){
	int l=0,r=0;
	for(int i=1;i<=n;i++){
		if(i<=r)zt[i]=min(z[i-l+1],r-i+1);
		else zt[i]=0;
		while(i+zt[i]<=n&&c[i+zt[i]]==rv[zt[i]+1])++zt[i];
		if(i+zt[i]>r)r=i+zt[i]-1,l=i;
	}
}
signed main(){
	scanf("%s",c+1);
	n=strlen(c+1);
	manacher();
	for(int i=1;i<=n;i++)rv[i]=c[n-i+1];
	ZAlgorithm();zzz();
	for(int i=1;i<=n;i++)pr[i]=max(pr[i-1],zt[i]);
	for(int i=1;i<=n;i++){
		int l=i-p[i]+1,r=i+p[i]-1;
		int L=0,R=min(n-r,l-1);
		while(L<=R){
			int k=(L+R)>>1;
			if(pr[l-k]>=k)L=k+1;
			else R=k-1;
		}
		if(R*2+p[i]*2-1>mx)ans=R,apos=i,mx=R*2+p[i]*2-1;
	}
	if(ans){
		printf("3\n");
		for(int i=1;i<=n;i++){
			if(zt[i]>=ans){
				printf("%d %d\n",i,ans);
				break;
			}
		} 
		printf("%d %d\n",apos-p[apos]+1,2*p[apos]-1);
		printf("%d %d\n",n-ans+1,ans);
	}else{
		printf("1\n%d %d\n",apos-p[apos]+1,2*p[apos]-1);
	}
	return 0;
}

标签:Tricky,Clever,int,题解,void,printf,ch,apos,ans
From: https://www.cnblogs.com/11-twentythree/p/18330087

相关文章

  • 关于网站安全狗卸载了仍然能拦截的问题解决
    关于网站安全狗卸载了仍然能拦截的问题解决如果你将所有safedog的文件删除的话,可能会导致Apache服务启动不了例如:这里没有提示相关安全狗的信息是因为我已经删除了Apache访问safedog的配置代码,只是提醒错误信息会如上图所示。导致这种原因的结果大概率是因为Apache的conf文件......
  • 题解:P4563 [JXOI2018] 守卫
    思路解法:区间DP。本题虽标上紫题,但黄队说了:“不要被颜色所吓倒。”易得,区间\([l,r]\)中最右端的亭子\(r\)一定会有保镖。先说一下可见性判断吧,只要\(l,r\)的连线的斜率大于\(p,r\)连成的线的斜率大,\(l\)即是可见的。如图,红线是\(r\)无法看到的,而蓝线是\(r\)可......
  • CF1178D Prime Graph 题解
    首先考虑一个问题:如果没有边数是素数的限制,应该怎么构造?这其实很简单,把原图连成一个环即可,每个点度数为\(2\)。接着考虑在原图上加边,注意到\(3\)也是个素数,所以每次可以任意选两个度数为\(2\)的点连边,此时仍然符合条件。这样加边最多可以加\(\left\lfloor\frac{n}{2}\rig......
  • CF685E 题解
    吐槽一下,为啥这道题\(\mathcal{O}(nm)\)可以过。联考的时候做到了这道题,还一直在想更快的算法。。。然后,这联考的数据是自己出的,有\(s=t\)的情况,我反正是完全没有想到,又因为是捆绑测试,直接痛失\(100pts\)。首先考虑转化一下题目。对于一个询问\(l,r,s,t\),就相当于是让你......
  • P4468[SCOI2007]折纸-题解
    题意:有一个左下角为\((0,0)\),右上角为\((100,100)\)的正方形,给你\(n\)个有向线段和\(m\)个询问,将纸片依次按直线折叠,然后每次询问让你求出某个点上有多少层纸。分析:观察到数据范围非常小,于是可以直接对于每个询问\(\mathcal{O}(2^n)\)来求。具体的,对于每一个点,倒着枚......
  • P8540 「Wdoi-2」夜空中的 UFO 恋曲 题解
    hanghangakioi考试的时候在乱猜结论,交了几遍就过了,证明当然是赛后才想的()文中加粗部分是需要读者稍微思考一下原因的地方(不是重点)。先考虑一下样例二,将\(10^{18}\)化成二进制:\(1101...001000000000000000000\)。其实只需要知道末尾有\(18\)个\(0\)就行了,因为在\(x\)......
  • CF1906C Cursed Game 题解
    题目大意交互库有一个\(3\times3\)的01矩阵\(a\),每次询问一个\(n\timesn\)的01矩阵\(b\),交互库会返回一个\((n-2)\times(n-2)\)的01矩阵\(c\),满足:\[c_{x,y}=\bigoplus\limits_{1\lei,j\le3}\left(a_{i,j}\operatorname{AND}b_{x+i-1,y+j-1}\right......
  • 梦熊十三连测第三场题解
    T1本题考察了数论的相关知识。30pts暴力枚举每次洗牌的情况,时间复杂度为\(O(n^2)\)。60pts首先卡牌\(1\)和\(2n\)一直不动,可以不用考虑这两张牌。将位置和剩下的牌上的数字全减\(1\),那么数字为\(k\)的牌操作一次后就会到\(2k\bmod(2n-1)\)的位置。那么问题相当......
  • Maximum Glutton题解
    正常动规,但是赛时死了。分析看到\(n\)很小,但是\(X\)和\(Y\)有点大,所以状态稍微改变一下。设\(dp_{i,j}\)表示已经选到第\(j\)个,且甜度为\(i\)时咸度的最小值。转移方程为:\[dp_{j,k}=\min_{0\lek\lei,a_i\lej\leX}(dp_{j,k},dp_{j-a_i,k-1}+b_i)\]按照\(i,j......
  • CF526G Spiders Evil Plan 题解
    Description给定一棵\(n\)个节点的无根树,每条边有边权。有\(q\)次询问,每次询问给出\(x,y\),你需要选择\(y\)条树上的路径,使这些路径形成一个包含\(x\)的连通块,且连通块中包含的边权和最大。\(n,q\le10^5\),强制在线。Solution考虑只有一组询问怎么快速求答案。容......