• G.Colorful String(The Preliminary Contest for ICPC Asia Xuzhou 2019)


    https://nanti.jisuanke.com/t/4

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 const int N=6e5+10,base =131;
     4 typedef unsigned long long ull;
     5 char str[N];
     6 ull hl[N],hr[N],p[N];
     7 
     8 int mark[N][30];
     9 
    10 
    11 ull get(ull h[],int l,int r)
    12 {
    13     return h[r]-h[l-1]*p[r-l+1];
    14 }
    15 
    16 int k=0;
    17 long long getval(int l,int r)
    18 {
    19     if(l==r&&str[r]=='z'+1)
    20         return 0;
    21     long long sum=0;
    22     if(str[l]=='z'+1)
    23         l++;
    24     for(int i=1;i<=26;++i)
    25     {
    26         int temp=(mark[r][i]-l+2)/2;
    27         if(temp<0)
    28             continue;
    29         sum+=temp;
    30     }
    31     return sum;
    32 }
    33 int main()
    34 {
    35 
    36 
    37     cin>>(str+1);
    38     int n=strlen(str+1);
    39 
    40     for(int i=n*2;i>0;i-=2)//重点i-=2 模拟kmp添加一个字符
    41     {
    42         str[i]=str[i/2];
    43         str[i-1]='z'+1;
    44         //中间插一个不需要的数
    45     }
    46 
    47     n=2*n;
    48     p[0]=1;
    49     for(int i=1;i<=n;++i)
    50     {
    51         for(int j=1;j<=26;++j)
    52         {
    53             mark[i][j]=mark[i-1][j];
    54             if(str[i]!='z'+1)
    55                 mark[i][str[i]-'a'+1]=i;
    56         }
    57     }
    58     for(int  i=1,j=n;i<=n;i++,j--)
    59     {
    60         hl[i]=hl[i-1]*base+str[i]-'a'+1;//正序的哈希值 ->
    61         hr[i]=hr[i-1]*base+str[j]-'a'+1;//逆序的哈希值 -> 这个是必要的
    62         p[i]=p[i-1]*base;
    63     }
    64 
    65 
    66     long long ans=0;
    67     for(int i=1;i<=n;i++)//枚举每一个字符作为中点
    68     {
    69         int l=0,r=min(i-1,n-i);
    70         while(l<r)
    71         {
    72             int mid=l+r+1>>1;//半径长度
    73 
    74 
    75             //if(get(hl,i-mid,i-1) != get(hl,i+1,i+mid) )
    76             //判读的确是左右区间的判断 但是 值却都是->方向的
    77             //所以这个就是必须要有逆序的原因
    78 
    79             if(get(hl,i-mid,i-1) !=get(hr,n-(i+mid)+1,n-(i+1)+1))
    80             {
    81                 //如果不符合 肯定是缩小半径
    82                 r=mid-1;
    83             }
    84             else l=mid;
    85         }
    86         ans+=getval(i-l,i);
    87     }
    88     printf("%lld
    ",ans);
    89     return 0;
    90 }

     

    1389

    解:

    字符串hash二分跑回文串。

  • 相关阅读:
    DS博客作业06--图
    DS博客作业05--树
    DS博客作业03--栈和队列
    DS博客作业02--线性表
    DS博客作业03--栈和队列
    DS博客作业02--线性表
    DS博客作业01--日期抽象数据类型设计与实现
    C语言博客作业06--结构体&文件
    C语言博客05--指针
    C语言博客作业04--数组
  • 原文地址:https://www.cnblogs.com/--HPY-7m/p/11482418.html
Copyright © 2020-2023  润新知