luogu P3279 [SCOI2013]密码

LINK:密码

给出来manacher的数组 让还原出字典序最小的字符串。字符集为小写字母。

当没有任何限制时 放字典序最小的'a'.如果此时还在最长的回文串中的话那么 直接得到当前字符即可。

注意这个过程要在上次放过的位置之后放 不能暴力放 暴力放是n^2的 确定位置跟原来的manacher是一致的。

最困难的是 当前位置不确定 前面那个也同时超出了前面串的回文半径。

随便加一个字符显然可能会出现错误。但是考虑到一个串的回文半径做完之后 当前位置不能和这个串之前的第一个字符相同 我们把这个东西在对应位置标记一下 然后不确定的时候从小到大选字符即可。

const int MAXN=100010<<1;
char a[MAXN];
int p[MAXN];
int n;
int vis[MAXN][26];
int main()
{
	freopen("1.in","r",stdin);
	get(n);
	rep(1,n,i)p[(i<<1)-1]=read();
	rep(1,n-1,i)p[i<<1]=read();
	int mid=0,mx=0;a[0]='#';
	rep(1,n*2-1,i)
	{
		if(mx<i)rep(0,25,j)if(!vis[i][j]){a[i]='a'+j;break;}
		for(int j=(mx>=i?min(mx-i+1,p[2*mid-i]):1);j<=p[i];++j)a[i+j]=a[i-j];
		if(i>p[i])vis[i+p[i]+1][a[i-p[i]-1]-'a']=1;
		if(i+p[i]>mx)mx=i+p[i],mid=i;
	}
	for(int i=1;i<=n*2;i+=2)putchar(a[i]);
	return 0;
}
原文地址:https://www.cnblogs.com/chdy/p/12663177.html