zoukankan      html  css  js  c++  java
  • Palindrome Degree(CodeForces 7D)—— hash求回文

      学了kmp之后又学了hash来搞字符串。这东西很巧妙,且听娓娓道来。

      这题的题意是:一个字符串如果是回文的,那么k值加1,如果前一半的串也是回文,k值再加1,以此类推,算出其k值。打个比方abaaba,k值为3,abaxxaba,k值为1。现在,给出一个串,让你求这个串的所有前缀(包括本身)的k值的和。

      如果考虑马拉车,那么先预处理出每个地方的最长回文长度,然后不断的截断,如果子串的回文长度大于其回文长度,那么k值加1,这样即可。但是马拉车写起来比较繁琐,没有模板我也没法手写。

      这里提供hash的方法。hash的方法就是给出一个素数,我这里是使用的17,然后就把字符串当做17进制,把每个位置的值和反过来计算的这个位置的值计算出来,然后每位一比对,如果相同,就在此处回文(显然,复杂度是O(n))。不过我觉得17可能不妥,因为s[i]的上限值是127,那么这个素数应当大于127才好,这里先暂时这样吧,如果不行就换233好了- 。-

      这东西怎么理解呢,打个比方121,在10进制看来从左往右的值和从右往左的值相同,那么它回文。

      具体见代码:

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <algorithm>
     4 #include <set>
     5 #include <iostream>
     6 using namespace std;
     7 typedef pair<int,int> pii;
     8 typedef unsigned long long ull;
     9 typedef long long ll;
    10 
    11 const int bas = 17;
    12 const int N = 5*(int)1e6+5;
    13 
    14 char s[N];
    15 int dp[N];
    16 
    17 int main()
    18 {
    19     scanf("%s",s+1);
    20     ull pre = s[1], suf = s[1], mul = 1;
    21     int len = strlen(s+1);
    22     ll ans = 1;
    23     dp[1]=1;
    24 
    25     for(int i=2;i<=len;i++)
    26     {
    27         mul *= bas;
    28         pre = pre + s[i] * mul;
    29         suf = suf * bas + s[i];
    30         if(pre == suf) dp[i] = dp[i>>1] + 1;
    31         ans += (ll)dp[i];
    32     }
    33     printf("%I64d
    ",ans);
    34     return 0;
    35 }
  • 相关阅读:
    yolo v2使用总结
    Oozie 实战之 shell
    Oozie 之 sqoop 实战
    Oozie 实战之 Hive
    Oozie wordcount实战
    Oozie 安装及 examples app 的使用
    Oozie是什么
    Flume使用(案例分析)
    一个数据仓库的设计架构
    Flume是什么
  • 原文地址:https://www.cnblogs.com/zzyDS/p/5647960.html
Copyright © 2011-2022 走看看