zoukankan      html  css  js  c++  java
  • [noi34]palindrome

    分割实际上就是不断地从两端取出一样的一段,并对剩下的串进行分割。下面我们来证明一下每一次贪心取出最短一段的正确性:

    考虑两种分割方式,分别表示成S=A+B+A和S=C+D+C,其中A就是最短的一段,那么当2|A|<|C|,显然就有C=A+E+A,那么就可以用三次划分来完成C,而当|A|<|C|<2|A|,即AC中重叠了,那么最短的前缀一定不是A,而是重叠部分(重叠部分既是A的前缀又是A的后缀)。

    那么这个贪心就成立了,用hash暴力判断即可。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define mod 1000000007
     4 #define ll long long
     5 #define N 1000001
     6 int t,l;
     7 ll sum[N],mi[N];
     8 char s[N];
     9 ll calc(int l,int r){
    10      return ((sum[r]-sum[l-1]*mi[r-l+1])%mod+mod)%mod;
    11 }
    12 int work(int l,int r){
    13     if (l>r)return 0;
    14     int mid=(l+r+1>>1),k=l;
    15     while ((k<mid)&&(calc(l,k)!=calc(l+r-k,r)))k++;
    16     if (k==mid)return 1;
    17     return work(k+1,l+r-k-1)+2;
    18 }
    19 int main(){
    20      mi[0]=1;
    21      for(int i=1;i<N;i++)mi[i]=(mi[i-1]*29)%mod;
    22      scanf("%d",&t);
    23      while (t--){
    24           scanf("%s",s);
    25           l=strlen(s);
    26           sum[0]=s[0]-'a'+1;
    27           for(int i=1;i<l;i++)sum[i]=(sum[i-1]*29+s[i]-'a'+1)%mod;
    28           printf("%d\n",work(0,l-1));
    29      }
    30 }
    View Code
  • 相关阅读:
    UITableView设置Cell左滑多个按钮(编辑,删除,置顶等)
    php处理ajax
    Vue实现增删改查功能
    Vue中slot内容分发
    两个Vue Demo
    js继承
    nodejs+express+mongodb搭建博客
    express中放置静态文件
    初始化一个Express项目
    mongodb使用1
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/11272226.html
Copyright © 2011-2022 走看看