3790: Magic Necklace Time limit: ten Sec Memory Limit: MB
Submit: 303 Solved: 149
[Submit] [Status] [Discuss] Description Mother's Day is coming, little H ready to give her a special necklace. This necklace can be seen as a string of lowercase letters, each lowercase letter representing a color. To make this necklace, little H bought two machines. The first machine can generate all forms of palindrome string, the second machine can connect two palindrome strings, and the second machine has a special property: If a string suffix and a string prefix is exactly the same, then you can overlap this repeating part. For example: ABA and ACA are connected and can generate string Abaaca or abaca. Now give the style of the target necklace and ask how many times you need to use the second machine to generate this special necklace.
Input data has multiple lines, one string per line, representing the style of the target necklace.
Output multiple lines, one answer per line indicates the minimum number of times a second machine needs to be used.
Sample InputABCDCBA
Abacada
ABCdefSample Output0
2
5HINT
Each test data, input no more than 5 lines
String length per line is less than or equal to 50000
Manacher + DP + Segment Tree
First, we use Manacher to find out all palindrome strings.
So the problem is: given some segments, ask at least a few segments to cover the entire range.
Line tree optimization dp done.
#include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <cstring > #include <algorithm> #define F (I,j,n) for (int. i=j;i<=n;i++) #define D (i,j,n) for (int i=j;i>=n;i--) # Define ll long long#define MAXN 100005#define inf 1000000000using namespace Std;int N,tot,f[maxn],mn[maxn*4];char S[MAXN] , ss[maxn];struct data{int x, y;} p[maxn];inline BOOL CMP (data A,data b) {return a.y==b.y?a.x<b.x:a.y<b.y;} void Manacher () {int mx=0,id=0; F (i,1,n) {if (mx>i) f[i]=min (Mx-i,f[id*2-i]), Else F[i]=0;while (S[i+f[i]]==s[i-f[i]]) f[i]++;if (I+F[I]>MX) mx=i +f[i],id=i;}} void build (int k,int l,int r) {mn[k]=inf;if (l==r) return;int mid= (l+r) >>1;build (K<<1,l,mid); Build (k< <1|1,MID+1,R);} void pushup (int k) {mn[k]=min (mn[k<<1],mn[k<<1|1]);} void change (int k,int l,int r,int pos,int val) {if (l==r) {mn[k]=min (mn[k],val); return;} int mid= (L+R) >>1;if (pos<=mid) Change (k<<1,l,mid,pos,val), Else change (k<<1|1,mid+1,r,pOs,val);p Ushup (k);} int query (int k,int l,int r,int l,int R) {if (l==l&&r==r) return mn[k];int mid= (l+r) >>1;if (R<=mid) return Query (K<<1,L,MID,L,R), else if (l>mid) return query (K<<1|1,MID+1,R,L,R), and Else return min (Query (k< <1,L,MID,L,MID), query (K<<1|1,mid+1,r,mid+1,r));} int main () {while (scanf ("%s", ss+1)!=eof) {int Len=strlen (ss+1); n=len<<1|1;s[0]= ' * '; s[1]= ' # '; s[n+1]= ' & '; F (i,1,n) s[i<<1]=ss[i],s[i<<1|1]= ' # '; Manacher (); tot=0; F (I,1,n) if (s[i]!= ' # ' | | f[i]>1) p[++tot]= (data) {(I-f[i])/2+1, (I+f[i])/2-1};sort (p+1,p+tot+1,cmp); int tmp=0; F (I,1,tot) if (!tmp| | P[TMP].Y!=P[I].Y) P[++tmp]=p[i];tot=tmp;n=len; F (i,1,n) f[i]=inf;build (1,0,n); change (1,0,n,0,0); F (I,1,tot) {f[p[i].y]=min (F[p[i].y],query (1,0,n,p[i].x-1,p[i].y-1) +1); Change (1,0,n,p[i].y,f[p[i].y]);} printf ("%d\n", f[n]-1);} return 0;}
bzoj3790 Magic Necklace