CF 835D D. Palindromic characteristics 字符串hash

题意。 定义k回文,一个是k回文的串

那么他本身是回文,并且左右相等,并且左右是k-1回文

问:一个S,所以字串分别是x回文?输出1----n回文的数目

思路:

直接暴力记忆化搜索!枚举判断就好了,回文和相等的条件都用hash判断就好了,注意下标问题!!!!尤其是回文时候的下标问题!!!


代码:

#include<bits/stdc++.h>
using namespace std;
#define MEM(a,b) memset(a,b,sizeof(a))
#define PB push_back
#define MP make_pair
#define X first
#define Y second
#define bug puts("bug");
typedef long long ll;
typedef pair<ll,ll> pii;
const double PI=acos(-1);
const int maxn=1e6+10;
int n;
string s;
int dp[5005][5005],ans[maxn],vis[5005][5005];
const int MAXN = 50100;
const unsigned long long SEED = 13331;
unsigned long long P[MAXN],S[MAXN],RS[MAXN];
unsigned long long HS(int l,int r){
    if(l==r) return s[l];
    ++l;++r;
    return S[r] - S[l-1]*P[r-l+1];
}
unsigned long long RHS(int l,int r){
    if(l==r) return s[l];
    l=n-l-1,r=n-r-1;swap(l,r);
    ++l;++r;
    return RS[r] - RS[l-1]*P[r-l+1];
}
void DFS(int l,int r){
    if(vis[l][r]) return;
    vis[l][r]=1;
    if(l==r){
        dp[l][r]=1;
        return;
    }
    int rr=(l+r-1)/2,ll=(l+r)/2+1;
    if(RHS(l,rr)==HS(ll,r)) dp[l][r]=1;
    DFS(l,rr);DFS(ll,r);
    if(dp[l][r]&&HS(l,rr)==HS(ll,r))
        dp[l][r]=min(dp[ll][r],dp[l][rr])+1;
}

int main(){
    P[0] = 1;
    for(int i = 1; i < MAXN; i++)P[i] = P[i-1] * SEED;
    cin>>s;
    MEM(vis,0);MEM(dp,0);MEM(ans,0);
    n=s.size();
    RS[0]=S[0] = 0;
    for(int i = 1; i <= n; i++)S[i] = S[i-1]*SEED + s[i-1];
    for(int i = 1; i <= n; i++)RS[i] = RS[i-1]*SEED + s[n-i];
    for(int i=0;i<n;i++)
        for(int j=i;j<n;j++)DFS(i,j);
    for(int i=0;i<n;i++)
        for(int j=i;j<n;j++)ans[dp[i][j]]++;
    for(int i=n-1;i>=1;i--) ans[i]+=ans[i+1];
    for(int i=1;i<=n;i++)
        printf("%d%c",ans[i]," 
"[i==n]);
    return 0;
}


原文地址:https://www.cnblogs.com/zhangxianlong/p/10672510.html