2018年10月17日提高组 T2 加密

版权声明:转载无所谓的。。。 https://blog.csdn.net/xuxiayang/article/details/83188088

大意

给定转换规则,试找到一个字符,使其与后面的字符所形成的子串按规则转换后是这个字符前构成的字符串的前缀,找到位置最靠前这个字符


思路

h a s h hash 判断是否相等即可


代码

#include<cstdio>
#include<cstring>
#include<iostream>
#define ri register int
using namespace std;char s[100001],s1[100001],to[26],cs[26];
const int base=233;
typedef unsigned long long ull;
int n,ans;
ull c[100001],h[100001],h1[100001];
inline ull gethash(ri l,ri r,ull h[]){return h[r]-h[l-1]*c[r-l+1];}
signed main()
{
	for(register int i=0;i<26;i++) cs[i]=getchar();getchar();
	gets(s+1);n=strlen(s+1);
	c[0]=1;
	for(register int i=0;i<26;i++) to[cs[i]-97]=i+97;//计算转换规则的逆运算
	for(register int i=1;i<=n;i++)
	{
		s1[i]=cs[s[i]-97];
		c[i]=c[i-1]*base;
		h[i]=h[i-1]*base+s[i]-97;
		h1[i]=h1[i-1]*base+s1[i]-97;//算出hash值
	}
	for(register int i=n&1?n/2+1:n/2;i<=n;i++)
	{
		ull x=gethash(1,n-i,h),y=gethash(1+i,n,h1);
		if(x==y) {ans=i;break;}//找到啦
	}
	for(register int i=1;i<=ans;i++) putchar(s[i]);
	for(register int i=1;i<=ans;i++) putchar(to[s[i]-97]);//输出
}

猜你喜欢

转载自blog.csdn.net/xuxiayang/article/details/83188088