zoukankan      html  css  js  c++  java
  • 【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 }
  • 相关阅读:
    str_pad 和 filter_var
    phpstorm主题下载地址
    php二维数组的排序
    wx.request出现400 bad request的问题
    php里的闭包函数
    关于宝塔下的项目中的php不能访问的问题
    字体大小适配宽度
    递归复制&查看文件夹下的指定后缀的文件
    find_in_set
    给动态ajax添加的元素添加click事件
  • 原文地址:https://www.cnblogs.com/myx12345/p/11593070.html
Copyright © 2011-2022 走看看