manacher
相比之前两个,拉车算是最好理解的了
- 模板题
hdu3068
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 using namespace std; 5 6 #define maxn 110005 7 char str[maxn],tstr[maxn<<1]; 8 int p[maxn<<1]; 9 int main(){ 10 freopen("1.in","r",stdin); 11 while(scanf("%s",str)!=EOF){ 12 int len=strlen(str); 13 int n=2*len+2; 14 tstr[0]='^',tstr[2*len+1]='#',tstr[2*len+2]='$'; 15 for(int i=0;i<len;i++){ 16 tstr[2*i+1]='#'; 17 tstr[2*i+2]=str[i]; 18 } 19 int idx=0,Bd=0,maxp=0; 20 for(int i=1;i<n;i++){ 21 p[i]=Bd>i?min(p[2*idx-i],Bd-i):1; 22 while(tstr[p[i]+i]==tstr[i-p[i]])p[i]++; 23 if(p[i]-1>maxp)maxp=p[i]-1; 24 if(i+p[i]-1>Bd){ 25 Bd=i+p[i]-1; 26 idx=i; 27 } 28 } 29 printf("%d\n",maxp); 30 } 31 return 0; 32 }
- 发现每次做的第二道题都是都要调好久,于是决定给它命名为坑B题
hdu3294
左右区间胡算的呢么,也是给自己跪下了,在注释里标下自己的罪行。。。感谢警察叔叔QAQ
#include<stdio.h> #include<algorithm> #include<string.h> using namespace std; #define maxn 200005 char haha[3],hnm[maxn],tstr[maxn<<1]; int p[maxn<<1]; int main(){ freopen("1.in","r",stdin); while(scanf("%s",haha)!=EOF){ scanf("%s",hnm); int len=strlen(hnm); int n=2*len+2; tstr[0]='^',tstr[2*len+1]='#',tstr[2*len+2]='$'; for(int i=0;i<len;i++){ tstr[2*i+1]='#'; tstr[2*i+2]=hnm[i]; } int idx=0,Bd=0,maxp=0,lol; for(int i=1;i<n;i++){ p[i]=Bd>i?min(p[2*idx-i],Bd-i):1; while(tstr[i-p[i]]==tstr[i+p[i]])p[i]++; if(p[i]-1>maxp){ maxp=p[i]-1; lol=i; } if(i+p[i]-1>Bd){ Bd=i+p[i]-1; idx=i; } } if(maxp<2)printf("No solution!\n"); else{ //int l=(lol-p[lol]+1)/2-1,r=(lol+p[lol]-1)/2-1; int l=(lol-maxp+1)/2-1,r=(lol+maxp-1)/2-1; printf("%d %d\n",l,r); for(int i=l;i<=r;i++)printf("%c",(hnm[i]-haha[0]+26)%26+'a'); printf("\n"); } } return 0; }
- 坑B t2
要求前半段增,后半段减的最长回文串,,,其实就是多加一个判断条件yooo~
1 #include<stdio.h> 2 #include<algorithm> 3 using namespace std; 4 5 #define maxn 100005 6 int n, T,str[maxn],tstr[maxn<<1],p[maxn<<1]; 7 8 int main(){ 9 freopen("1.in","r",stdin); 10 scanf("%d",&T); 11 while(T--){ 12 scanf("%d",&n); 13 for(int i=0;i<n;i++) 14 scanf("%d",&str[i]); 15 int len=2*n+2; 16 tstr[0]=-1,tstr[n*2+1]=0,tstr[n*2+2]=-2; 17 for(int i=0;i<n;i++){ 18 tstr[i*2+1]=0; 19 tstr[i*2+2]=str[i]; 20 } 21 int idx=0,Bd=0,maxp=0; 22 for(int i=1;i<len;i++){ 23 p[i]=Bd>i?min(p[idx*2-i],Bd-i):1; 24 while(tstr[i-p[i]]==tstr[i+p[i]]&&tstr[i-p[i]]<=tstr[i-p[i]+2]) 25 p[i]++; 26 if(p[i]-1>maxp)maxp=p[i]-1; 27 if(i+p[i]-1>Bd){ 28 Bd=i+p[i]-1; 29 idx=i; 30 } 31 } 32 printf("%d\n",maxp); 33 } 34 return 0; 35 }
- 老爷题
uoj103
1 #include<stdio.h> 2 #include<algorithm> 3 #include<string.h> 4 using namespace std; 5 6 #define maxn 300005 7 typedef long long i64; 8 char str[maxn],tstr[maxn<<1]; 9 int sa[maxn],rank[maxn],height[maxn],haha[maxn],x[maxn],y[maxn],tong[maxn]; 10 int log[maxn],dp[maxn][20],p[maxn<<1]; 11 bool cmp(int *nxt,int a,int b,int j){ 12 return nxt[a]==nxt[b]&&nxt[a+j]==nxt[b+j]; 13 } 14 void SA(int n,int m){ 15 int i,j,p,*cur=x,*nxt=y; 16 for(i=0;i<m;i++)tong[i]=0; 17 for(i=0;i<n;i++)tong[cur[i]=str[i]]++; 18 for(i=1;i<m;i++)tong[i]+=tong[i-1]; 19 for(i=n-1;i>=0;i--)sa[--tong[cur[i]]]=i; 20 21 for(p=1,j=1;p<n;j*=2,m=p){ 22 23 for(p=0,i=n-j;i<n;i++)nxt[p++]=i; 24 for(i=0;i<n;i++)if(sa[i]>=j)nxt[p++]=sa[i]-j; 25 26 for(i=0;i<m;i++)tong[i]=0; 27 for(i=0;i<n;i++)haha[i]=cur[nxt[i]]; 28 for(i=0;i<n;i++)tong[haha[i]]++; 29 for(i=1;i<m;i++)tong[i]+=tong[i-1]; 30 for(i=n-1;i>=0;i--)sa[--tong[haha[i]]]=nxt[i]; 31 for(swap(cur,nxt),p=1,cur[sa[0]]=0,i=1;i<n;i++) 32 cur[sa[i]]=cmp(nxt,sa[i-1],sa[i],j)?p-1:p++; 33 } 34 } 35 void calheight(int n){ 36 int i,j,k=0; 37 for(i=1;i<=n;i++)rank[sa[i]]=i; 38 for(i=0;i<n;height[rank[i++]]=k) 39 for(k?k--:0,j=sa[rank[i]-1];str[i+k]==str[j+k];k++); 40 41 log[1]=0; 42 for(i=2;i<=n;i++)log[i]=log[i/2]+1; 43 for(i=1;i<=n;i++)dp[i][0]=height[i]; 44 for(j=1;(1<<j)<=n;j++) 45 for(int i=1;i<=n;i++) 46 dp[i][j]=min(dp[i][j-1],dp[i+(1<<(j-1))][j-1]); 47 } 48 int st(int l,int r){ 49 int len=r-l+1; 50 return min(dp[l][log[len]],dp[r-(1<<log[len])+1][log[len]]); 51 } 52 i64 yoho(int lef,int rig,int n){ 53 lef=(lef-1)/2,rig=(rig-2)/2; 54 int pos=rank[lef],cd=rig-lef+1,res=1; 55 int l=0,r=pos; 56 while(l<r-1){ 57 int mid=(l+r)/2; 58 if(st(mid+1,pos)>=cd)r=mid; 59 else l=mid; 60 } 61 res+=pos-r; 62 l=pos,r=n+1; 63 while(l<r-1){ 64 int mid=(l+r)/2; 65 if(st(pos+1,mid)>=cd)l=mid; 66 else r=mid; 67 } 68 res+=l-pos; 69 return (i64)res*cd; 70 } 71 void manacher(int n){ 72 int len=2*n+2; 73 i64 ans=0; 74 tstr[0]='^',tstr[2*n+1]='#',tstr[2*n+2]='$'; 75 for(int i=0;i<n;i++){ 76 tstr[2*i+1]='#'; 77 tstr[2*i+2]=str[i]; 78 } 79 int idx=0,Bd=0; 80 for(int i=1;i<len;i++){ 81 p[i]=Bd>i?min(p[2*idx-i],Bd-i):1; 82 while(tstr[i+p[i]]==tstr[i-p[i]]){ 83 if(i+p[i]>Bd)ans=max(ans,yoho(i-p[i],i+p[i],n)); 84 p[i]++; 85 } 86 if(i+p[i]-1>Bd){ 87 Bd=i+p[i]-1; 88 idx=i; 89 } 90 } 91 printf("%lld\n",ans); 92 } 93 int main(){ 94 freopen("1.in","r",stdin); 95 scanf("%s",str); 96 int len=strlen(str); 97 str[len]=0; 98 SA(len+1,128); 99 calheight(len); 100 manacher(len); 101 return 0; 102 }
prey式二分,美,,,但l和r初值要把人搞飞了,基本上机房最后都在调二分,无爱