zoukankan      html  css  js  c++  java
  • 2017.10.6 国庆清北 D6T3 字符串

    题目描述

    如果把一个字符串从头到尾翻转后和原字符串相等,我们称之为回文串,比如“aabaa”、“())(”、“2017102”。

    如果一个字符串存在两个出现过的字母出现的次数相等,我们称之为好

    的字符串。

    现在给一个由小写字母组成的字符串,问在这个字符串的所有连续的串

    中,好的回文串有多少个。(两个相同的回文串出现在不同位置算多次)。

    输入输出格式

    输入格式:

    一行一个小写字母组成的字符串。

    输出格式:

    一行一个整数,表示答案。

    输入输出样例

    输入样例#1:
    abcbaabcba
    输出样例#1:
    6
    【样例解释】
    abcba s[1..5] a,b 出现次数相等
    baab s[4..7] a,b 出现次数相等
    cbaabc s[3..8] a,b 出现次数相等
    bcbaabcb s[2..9] a,c 出现次数相等
    abcbaabcba s[1..10] a,b 出现次数相等
    abcba s[6..10] a,b 出现次数相等

    说明

    len 表示字符串长度。

    对于30% 的数据, len <=10^2。

    对于60% 的数据, len <= 10^3。

    对于100% 的数据,1 <= len <= 10^4。

      1 /*
      2 我们发现回文串是可以二分的
      3 比如:bbbabcbaabcba 我们以第1个c为中心,发现回文半径是3,大于3一定不是回文串。当回文串长度为偶数的时候,我们需要特殊处理一下。
      4 现在有一个结论:本质不同的回文串个数只有O(N)个
      5 本质不同:字符串本身是不同的。
      6 每一次处理完回文串,我们要把他的hash值记录下来。
      7 */
      8 
      9 #include<cstdio>
     10 #include<cstring>
     11 #include<algorithm>
     12 #include<map>
     13 using namespace std;
     14 
     15 typedef unsigned long long ULL;
     16 typedef long long LL;
     17 
     18 char s[10005];
     19 ULL h[10005],rh[10005],pw[10005];
     20 int L;
     21 
     22 ULL hs(int l,int r)
     23 {
     24     return h[r]-h[l-1]*pw[r-l+1];
     25 }
     26 ULL rhs(int l,int r)
     27 {
     28     return rh[l]-rh[r+1]*pw[r-l+1];
     29 }
     30 struct N
     31 {
     32     int a[26];
     33     bool ok(){
     34         int b[26];
     35         for(int i=0;i<26;i++) b[i]=a[i];
     36         sort(b,b+26);
     37         for(int i=0;i<25;i++)
     38         {
     39             if(b[i]>0&& b[i] == b[i+1]) return true;
     40         }
     41         return false;
     42     }
     43     void clear()
     44     {
     45         memset(a,0,sizeof a);
     46     }
     47 };
     48 LL ans=0;
     49 map<ULL,LL> num;
     50 map<ULL,N> A;
     51 void solve_odd()    //奇数 
     52 {
     53     for(int i=1;i<=L;i++)
     54     {
     55         int l=1,r=min(i,L-i+1)+1;
     56         while(r-l>1)
     57         {
     58             int mid=(l+r)/2;
     59             if(hs(i-mid+1,i+mid-1)==rhs(i-mid+1,i+mid-1)) l=mid;
     60             else r=mid;
     61         }
     62         int p=l;
     63         int tmp=p;
     64         while(tmp>=1&&num.find(hs(i-tmp+1,i+tmp-1))==num.end()) tmp--;
     65         LL sum=0;
     66         N st;
     67         st.clear();
     68         if(tmp>=1)
     69         {
     70             sum=num[hs(i-tmp+1,i+tmp-1)];
     71             st=A[hs(i-tmp+1,i+tmp-1)];
     72         }
     73         while(tmp<p)
     74         {
     75             st.a[s[i+tmp]-'a']+=(tmp==0?1:2);
     76             if(st.ok()) sum++;
     77             num[hs(i-tmp,i+tmp)]=sum;
     78             A[hs(i-tmp,i+tmp)]=st;
     79             tmp++;
     80         }
     81         ans+=sum;
     82     }
     83 }
     84 void solve_even()    //偶数 
     85 {
     86     A.clear();
     87     num.clear();
     88     for(int i=1;i<L;i++)
     89     {
     90         int l=1,r=min(i,L-i)+1;
     91         while(r-l>1)
     92         {
     93             int mid=(l+r)/2;
     94             if(hs(i-mid+1,i+mid)== rhs(i-mid+1,i+mid)) l=mid;
     95             else r=mid;
     96         }
     97         int p=l;
     98         int tmp=p;
     99         while(tmp>=1&&num.find(hs(i-tmp+1,i+tmp))==num.end()) tmp--;
    100         LL sum = 0;
    101         N st;
    102         st.clear();
    103         if(tmp>=1)
    104         {
    105             sum=num[hs(i-tmp+1,i+tmp)];
    106             st=A[hs(i-tmp+1,i+tmp)];
    107         }
    108         while(tmp<p)
    109         {
    110             st.a[s[i+tmp+1]-'a']+=2;
    111             if(st.ok()) sum++;
    112             num[hs(i-tmp,i+tmp+1)]=sum;
    113             A[hs(i-tmp,i+tmp+1)]=st;
    114             tmp++;
    115         }
    116         ans+=sum;
    117     }
    118 }
    119 
    120 int main()
    121 {
    122     scanf("%s",s+1);
    123     L=strlen(s+1);
    124     s[0]='#';
    125     pw[0]=1;
    126     for(int i=1;i<=L;i++) pw[i]=pw[i-1]*13131;        ///hash值 
    127     for(int i=1;i<=L;i++) h[i]=h[i-1]*13131+s[i];
    128     for(int i=L;i>=1;i--) rh[i]=rh[i+1]*13131+s[i];
    129     solve_odd();
    130     solve_even();
    131     printf("%lld
    ",ans);
    132     fclose(stdout);
    133     return 0;
    134 }
    View Code
  • 相关阅读:
    6-Python爬虫-分布式爬虫/Redis
    ES 查询时 排序报错(fielddata is disabled on text fileds by default ... )解决方法
    Intellij Idea webstorm 激活
    Intellij Idea 配置jdk
    java 获取(格式化)日期格式
    js 跳转 XSS漏洞 预防
    CSS去掉背景颜色
    js对象无法当成参数传递 解决方法
    Elasticsearch java api
    java多条件查询SQL语句拼接的小技巧
  • 原文地址:https://www.cnblogs.com/lovewhy/p/7653031.html
Copyright © 2011-2022 走看看