LightOJ1258(线性回文串
题目:给出一个序列,求最少在后面加多少字符形成一个回文串。
思路:裸的manacher,注意枚举的起点和终点。
/* * @author: Cwind */ ///#pragma comment(linker, "/STACK:102400000,102400000") #include <iostream> #include <map> #include <algorithm> #include <cstdio> #include <cstring> #include <cstdlib> #include <vector> #include <queue> #include <stack> #include <functional> #include <set> #include <cmath> using namespace std; #define IOS std::ios::sync_with_stdio (false);std::cin.tie(0) #define pb push_back #define PB pop_back #define bk back() #define fs first #define se second #define sq(x) (x)*(x) #define eps (3e-7) #define IINF (1<<29) #define LINF (1ll<<59) #define INF (1000000000) #define FINF (1e3) #define clr(x) memset((x),0,sizeof (x)); typedef long long ll; typedef unsigned long long ull; typedef pair<int,int> pii; typedef pair<int,int> P; const int maxv=1e6+300; char r[maxv]; char s[maxv*2]; int p[maxv*2]; int n; int len; void manacher(){ s[0]='&'; for(int i=0;i<len;i++){ s[2*i+1]='#'; s[2*i+2]=r[i]; } s[2*len+1]='#'; s[2*len+2]='*'; int mx=0,mxid=0; for(int i=1;i<=2*len;i++){ if(mx>i){ p[i]=min(p[mxid*2-i],mx-i); }else{ p[i]=1; } for(;s[i-p[i]]==s[i+p[i]];p[i]++); if(p[i]+i>mx){ mx=p[i]+i; mxid=i; } } } int T; int cas; int main(){ freopen("/home/slyfc/CppFiles/in","r",stdin); //freopen("defense.in","r",stdin); //freopen("defense.out","w",stdout); cin>>T; while(T--){ scanf("%s",r); len=strlen(r); manacher(); int maxx=0; for(int i=len*2;i>=2;i--){ if(p[i]==len*2-i+2) maxx=len*2-i+2; } maxx--; printf("Case %d: %d\n",++cas,2*len-maxx); } return 0; }