zoukankan      html  css  js  c++  java
  • BZOJ 2084: [Poi2010]Antisymmetry(Hash+二分)

    求一个01序列的子串取反并反转后与原串相同的个数.

    很显而易见的是,反转的话只要子串对应的i和n-i+1位相反即可,这个看一下样例能很快看出来.

    所以我们正着求一遍hash,反着取反然后求hash.

    枚举中间点,二分一下这个子串长度的一半,check的话就是判断前一半子串的正hash值与后一半子串取反后的反hash值是否相等.

    答案怎么统计呢,显然,如果一个子串满足条件,那么去掉首位得到的子串也满足条件,ans+=len/2...

    然而细节写错wa了2发。。。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <algorithm>
     4 #include <cstring>
     5 #include <cmath>
     6 #include <queue>
     7 #include <map>
     8 #define ll long long
     9 #define out(a) printf("%lld ",a)
    10 #define writeln printf("
    ")
    11 const int N=5e5+50;
    12 const int MOD=1e9+7;
    13 const int base=233;
    14 using namespace std;
    15 int n;
    16 char s[N];
    17 ll Hash1[N],Hash2[N],Pow[N];
    18 ll ans;
    19 int read()
    20 {
    21      int s=0,t=1; char c;
    22      while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();}
    23      while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();}
    24      return s*t;
    25 }
    26 ll readl()
    27 {
    28      ll s=0,t=1; char c;
    29      while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();}
    30      while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();}
    31      return s*t;
    32 }
    33 ll get(int l,int r,int x)
    34 {
    35     if (x==1) return (Hash1[r]-(ll)Hash1[l-1]*Pow[r-l+1]%MOD+MOD)%MOD;
    36     return (Hash2[l]-(ll)Hash2[r+1]*Pow[r-l+1]%MOD+MOD)%MOD;
    37 }
    38 int solve(int x)
    39 {
    40     int l=1,r=min(x,n-x),mid=0; bool flag=false;
    41     while (l<=r){
    42       mid=(l+r)>>1;
    43       if (get(x-mid,x+mid-1,1)==get(x-mid,x+mid-1,2)) flag=true,l=mid+1;
    44       else r=mid-1;
    45     }
    46     //out(x),out(r),writeln;
    47     if (flag) return r;
    48     return 0;
    49 }
    50 int main()
    51 {
    52     n=read(); Pow[0]=1;
    53     scanf("%s",s);
    54     for (int i=1;i<=n;i++)
    55       Pow[i]=Pow[i-1]*base%MOD;
    56     for (int i=0;i<n;i++)
    57       Hash1[i]=(Hash1[i-1]*base+s[i])%MOD;
    58     for (int i=n-1;i>=0;i--)
    59       Hash2[i]=(Hash2[i+1]*base+(48+49-s[i]))%MOD;
    60     for (int i=1;i<n;i++)
    61       ans+=solve(i);
    62     out(ans);
    63     return 0;
    64 }
    View Code
  • 相关阅读:
    如何确定Kafka的分区数、key和consumer线程数
    Storm程序永久代内存溢出
    JVM堆内存相关的启动参数:年轻代、老年代和永久代的内存分配
    Git添加本地项目出现fatal: unable to get credential storage lock: File exists
    Kafka的通讯协议
    文件上传 数据对比
    jquery 弹出层
    XSS 简单理解之:AntiSamy
    XSS 简单理解
    超人说我最叼蝙蝠侠笑了 超级英雄战力排名
  • 原文地址:https://www.cnblogs.com/Kaleidoscope233/p/9563082.html
Copyright © 2011-2022 走看看