hdu4513吉哥系列故事——完美队形II 马拉车
题意:求最长回文串长度,要求回文串左边是非下降。
思路一:
先把连续的回文串,满足先上升再下降的序列处理出来,再对这部分序列做马拉车模板就可以了。
需要注意的是,由于他要的是非下降的序列,所以要注意等于的情况。
还需要注意的是,写马拉车的板子习惯用的是char。。但是char的上限是255,'0'+250会爆char。因为这个wa了好几天也没想出bug是什么。
思路二:
对马拉车算法进行修改,只要在判断回文的时候加入递增这个条件即可。
两个思路都实现了一遍。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> #define clr(a,b) memset(a,b,sizeof(a)) using namespace std; typedef long long ll; const int maxn=110010; int s[maxn<<1],ne[maxn<<1]; int p[maxn<<1],mx,maxx,n,T,a[maxn<<1],b[maxn],cnt; int init(int b[],int len){ int j=2; ne[0]='$',ne[1]='#'; for(int i=1;i<=len;i++) { ne[j++]=('0'+b[i]); ne[j++]='#'; } ne[j]='\0'; return j; } void Manacher(int b[],int len) { if(len==0)return; len=init(b,len); int id,ma=0; for(int i=1;i<len;i++) { if(i<ma){ p[i]=min(p[2*id-i],ma-i); }else p[i]=1; while(ne[i-p[i]]==ne[i+p[i]])p[i]++; maxx=max(maxx,p[i]); if(i+p[i]>ma){ ma=i+p[i]; id=i; } } } int main(){ // printf("%d %d %d\n",'#','$','\0'); cin>>T; while(T--) { cin>>n; for(int i=1;i<=n;i++) { scanf("%d",&a[i]); } cnt=0,maxx=0; int flag=0; for(int i=1;i<=n;i++) { if(a[i]>=a[i-1]&&flag==0){ b[++cnt]=a[i]; }else if(a[i]<=a[i-1]){ flag=1; b[++cnt]=a[i]; }else{ Manacher(b,cnt); cnt=flag=0; int j=i-1; while(a[j]<=a[j+1]){ if(j==0)break; b[++cnt]=a[j]; j--; } b[++cnt]=a[i]; } } Manacher(b,cnt); printf("%d\n",maxx-1); } }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> #define clr(a,b) memset(a,b,sizeof(a)) using namespace std; typedef long long ll; const int maxn=110010; int s[maxn<<1],ne[maxn<<1]; int p[maxn<<1],mx,maxx,n,T,a[maxn<<1],b[maxn<<1],cnt; int init(){ int j=2; ne[0]=-1; ne[1]=300; for(int i=1;i<=n;i++) { ne[j++]=a[i]; ne[j++]=300; } ne[j]=-3; //printf("j:%d n:%d\n",j,n); return j; } int Manacher(){ int len=init(); int id,ma=0,mx=0; //printf("len:%d\n",len); for(int i=1;i<len;i++) { if(i<ma){ p[i]=min(p[2*id-i],ma-i); }else p[i]=1; int k=ne[i]; while(ne[i-p[i]]==ne[i+p[i]]&&(ne[i-p[i]]==300||ne[i-p[i]]<=k)){ if(ne[i-p[i]]!=300)k=ne[i-p[i]]; p[i]++; } if(i+p[i]>ma){ ma=i+p[i]; id=i; } mx=max(mx,p[i]); // printf("i:%d mx:%d\n",i,mx); } return mx-1; } int main(){ cin>>T; while(T--) { cin>>n; for(int i=1;i<=n;i++) { scanf("%d",&a[i]); } maxx=Manacher(); cout<<maxx<<endl; } }
——愿为泰山而不骄
qq850874665~~