【HDOJ6599】I Love Palindrome String(PAM,manacher)

题意:给出一个由小写字母组成的长为n的字符串S,定义他的子串【L,R】为周驿东串当且仅当【L,R】为回文串且【L,(L+R)/2】为回文串

求i=【1,n】 所有长度为i的周驿东串的个数

n<=3e5

思路:PAM把所有回文串找出来,记录一下在原串S中的位置和长度,最后check每个结点是不是周驿东串

check部分可以正反两次哈希,N=3e5应该要双哈

我是用manacher预处理出每个位置为中心的回文串的最大长度,check就直接看一下(l+mid)/2这个位置的长度有没有r-mid+1

std里还判了右半部分,迷惑行为

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 typedef long long ll;
  4 typedef unsigned int uint;
  5 typedef unsigned long long ull;
  6 typedef pair<int,int> PII;
  7 typedef pair<ll,ll> Pll;
  8 typedef vector<int> VI;
  9 typedef vector<PII> VII;
 10 typedef pair<ll,ll>P;
 11 #define N  700010
 12 #define M  200010
 13 #define fi first
 14 #define se second
 15 #define MP make_pair
 16 #define pi acos(-1)
 17 #define mem(a,b) memset(a,b,sizeof(a))
 18 #define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++)
 19 #define per(i,a,b) for(int i=(int)a;i>=(int)b;i--)
 20 #define lowbit(x) x&(-x)
 21 #define Rand (rand()*(1<<16)+rand())
 22 #define id(x) ((x)<=B?(x):m-n/(x)+1)
 23 #define ls p<<1
 24 #define rs p<<1|1
 25 
 26 const ll MOD=1e9+7,inv2=(MOD+1)/2;
 27       double eps=1e-4;
 28       ll INF=1ll<<60;
 29       ll inf=5e13;
 30       int dx[4]={-1,1,0,0};
 31       int dy[4]={0,0,-1,1};
 32 
 33 char s[N];
 34 int ans[N],aid[N],p[N],a[N],ID;
 35 
 36 int read()
 37 {
 38    int v=0,f=1;
 39    char c=getchar();
 40    while(c<48||57<c) {if(c=='-') f=-1; c=getchar();}
 41    while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar();
 42    return v*f;
 43 }
 44 
 45 void manacher(char *ch,int len)
 46 {
 47     rep(i,1,len*2+10) a[i]=-1;
 48     int n=2; a[1]=26; a[2]=27;
 49     rep(i,1,len)
 50     {
 51         a[++n]=ch[i]-'a'; aid[i]=n;
 52         a[++n]=27;
 53     }
 54     a[++n]=28;
 55     rep(i,0,n) p[i]=0;
 56     int mx=0,id=0;
 57     rep(i,2,n-1)
 58     {
 59         if(mx>i) p[i]=min(p[2*id-i],mx-i);
 60          else p[i]=1;
 61         while(a[i+p[i]]==a[i-p[i]]) p[i]++;
 62         if(p[i]+i>mx)
 63         {
 64             mx=p[i]+i;
 65             id=i;
 66         }
 67     }
 68     rep(i,2,n-1) p[i]--;
 69 }
 70 
 71 int isok(int l,int r)
 72 {
 73     int mid=(l+r)>>1;
 74     int t=(p[(aid[l]+aid[mid])>>1]>=mid-l+1);
 75     return t;
 76 }
 77 
 78 struct pam
 79 {
 80     int q,p,cnt[N],num[N],f[N],len[N],id[N],ch[N][26];
 81 
 82     pam(){}
 83 
 84     void init()
 85     {
 86         rep(i,0,ID)
 87         {
 88             len[i]=f[i]=num[i]=id[i]=cnt[i]=0;
 89             rep(j,0,25) ch[i][j]=0;
 90         }
 91         ID=1;
 92         f[0]=f[1]=1; len[1]=-1;
 93     }
 94 
 95     void add(int x,int n)
 96     {
 97         while(s[n-len[p]-1]!=s[n]) p=f[p];
 98         if(!ch[p][x])
 99         {
100             int q=++ID,k=f[p];
101             len[q]=len[p]+2;
102             while(s[n-len[k]-1]!=s[n]) k=f[k];
103             f[q]=ch[k][x];
104             ch[p][x]=q;
105             num[q]=num[f[q]]+1;
106         }
107         p=ch[p][x];
108         cnt[p]++;
109         id[p]=n;
110     }
111 
112     void solve()
113     {
114         per(i,ID,0) cnt[f[i]]+=cnt[i];
115         rep(i,0,ID)
116          if(len[i]>0)
117           ans[len[i]]+=isok(id[i]-len[i]+1,id[i])*cnt[i];
118     }
119 }pam;
120 
121 
122 
123 int main()
124 {
125     while(scanf("%s",s+1)!=EOF)
126     {
127         int n=strlen(s+1);
128         pam.init();
129         rep(i,1,n) ans[i]=0;
130         rep(i,1,n) pam.add(s[i]-'a',i);
131         manacher(s,n);
132         pam.solve();
133         rep(i,1,n-1) printf("%d ",ans[i]);
134         printf("%d
",ans[n]);
135     }
136 
137     return 0;
138 }
原文地址:https://www.cnblogs.com/myx12345/p/11593070.html