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初值要把人搞飞了,基本上机房最后都在调二分,无爱

posted @ 2015-11-20 16:32  Ngshily  阅读(323)  评论(0编辑  收藏  举报