zoukankan      html  css  js  c++  java
  • 【Manacher】Colorful String

    The value of a string s is equal to the number of different letters which appear in this string.
    
    Your task is to calculate the total value of all the palindrome substring.
    
    Input
    The input consists of a single string |s|(1≤∣s∣≤3×10^5 ).
    
    The string s only contains lowercase letters.
    
    Output
    Output an integer that denotes the answer.
    
    样例输入 
    abac
    
    样例输出 
    6
    
    样例解释
    abac has palindrome substrings a,b,a,c,abaa,b,a,c,aba,ans the total value is equal to 1+1+1+1+2=6

    【题解】

      Manacher,先预处理一波,然后找出每一个位置的26个字母下一个位置,存在一个vector里面,然后最后找的时候就是差值 × 对应的个数。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int N=3e5+100;
     5 char S[N],T[N<<1];
     6 int Len[N*2];
     7 int nxt[N][27];
     8 vector<int>V[N];
     9 void Manacher(char *s){
    10     int L=strlen(s);
    11     int po = 0 , mx=0 ;
    12 
    13     for(int i=1;i<=L*2;i++){
    14         T[i] = i&1? '#' : s[i/2-1] ;
    15     }
    16 
    17     T[0] = '@';
    18     T[2*L+1] = '#';
    19     T[2*L+2] = '';
    20 
    21     ll tmp = 0 ;
    22     for(int i=1;i<=2*L;i++){
    23         if( i<mx ){
    24             Len[i]=min( mx-i , Len[2*po-i] );
    25         }else{
    26             Len[i] = 1 ;
    27         }
    28 
    29         while( T[i+Len[i]]==T[i-Len[i]] ){
    30             Len[i]++;
    31         }
    32         if( i + Len[i] > mx ){
    33             po = i;
    34             mx = i + Len[i];
    35         }
    36     }
    37 }
    38 int main()
    39 {
    40     scanf("%s",S);
    41     Manacher(S);
    42     int len1 = strlen( S ) ;
    43     int len2 = strlen( T ) ;
    44 
    45     for( int j = 0 ; j < 26 ; j++ ){
    46         int pos = INT_MAX ;
    47         for( int i = len1 - 1 ; i >= 0 ; i-- ){
    48             if( S[i] == j + 'a' ) pos = i ;
    49             nxt[i][j] = pos ;
    50         }
    51     }
    52 
    53 
    54     for( int i = 0 ; i < len1 ; i++ ){
    55         for( int j = 0 ; j < 26 ; j++ ){
    56             V[i].push_back( nxt[i][j] ) ;
    57         }
    58         sort( V[i].begin() , V[i].end() );
    59     }
    60     /*
    61     for( int i = 1 ; i < len2 ; i++ ){
    62         printf("%d : %c , Len %d 
    ",i , T[i] , Len[i] );
    63     }
    64     */
    65     ll ans = 0 ;
    66     for( int i = 2 ; i < len2 ; i++ ){
    67         int L = Len[i] / 2 ;
    68         if( L == 0 ) continue ;
    69 
    70         int Id = i / 2 - 1 ;
    71         if( i & 1 ) Id ++ ;
    72 
    73         int RR = Id + L - 1 ;
    74         int Last = V[Id][0] ;
    75         int cnt = 0  ;
    76         for( auto x : V[Id] ){
    77             if( x > RR ) break ;
    78             int r = x - 1 ;
    79             ans = ans + (ll)( cnt ++ ) * (ll) ( r - Last + 1 );
    80             Last = x ;
    81         }
    82         if( RR >= Last ){
    83             ans = ans + (ll) cnt * (ll) ( RR - Last + 1 );
    84         }
    85     }
    86     printf("%lld
    ",ans);
    87     return 0;
    88 }
    89 
    90 //jswbutgecnmqnuagqnvxfljfffzvudcfvygpro
    View Code
  • 相关阅读:
    【转载】nio介绍+原理+传统IO原理+与传统IO区别+案例
    【Ubuntu】制作执行脚本 | 打包一串命令顺序执行
    Ubuntu 使用教程集锦
    【转载】自定义地图数据瓦片化请求的一种实现方案
    【转载】ROS机器人程序设计 | 期末知识点大总结
    【转载】三维重建(三)相机参数标定与光束平差法(Bundle Adjustment)
    【阅读笔记】《大话数据挖掘》定义和功能
    【转载】C++对象成员与构造函数
    【转载】IP地址和子网划分学习笔记之《子网掩码详解》
    STM32的启动过程一
  • 原文地址:https://www.cnblogs.com/Osea/p/11483538.html
Copyright © 2011-2022 走看看