zoukankan      html  css  js  c++  java
  • [ POI 2010 ] Antisymmetry

    (\)

    (Description)


    给出一个长度为 (N) 的二进制串,定义一个子串是优秀的,当且仅当其正着看,和倒着按位取反后看结果是一样的,求整个串有多少个优秀的子串。

    • (Nle 5 imes10^5)

    (\)

    (Solution)


    挺好的一道 (Manacher) 变式题。

    考虑合法的串满足的条件:

    • 首先因为要按位取反,所以一定不存在奇数长度的合法解,因为对称轴的那个字符取反后一定不等于原来的字符。

    • 然后考虑反序的过程,如果没有按位取反实际上这就是一个回文串,我们不妨定义 (trs) 数组,表示取反后的答案,有:

      [trs[0]=1,trs[1]=1,trs[#]=#,trs[ [ ]= [ ,trs[ ] ]= ] ]

    然后就可以愉快的 (Manacher) 了。

    注意,由于第一条性质,回文中心只会选取在添加字符 (#) 的位置。注意计数的时候要去掉 (#) 号的影响,答案累加半径的一半。

    (\)

    (Code)


    #include<cmath>
    #include<cstdio>
    #include<cctype>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define R register
    #define gc getchar
    #define N 1000010
    using namespace std;
    
    int n,len,s[N],trs[10],res[N];
    
    long long ans;
    
    int main(){
      scanf("%d",&n);
      char c=gc(); while(!isdigit(c)) c=gc();
      s[0]=3; s[1]=2; s[len=2]=c-'0';
      for(R int i=2;i<=n;++i){
        s[++len]=2; s[++len]=gc()-'0';
      }
      s[len+1]=4; trs[0]=1; trs[1]=0;
      trs[2]=2; trs[3]=3; trs[4]=4;
      for(R int i=1,mr=0,p=0;i<=len;i+=2){
        res[i]=(i>mr)?1:min(mr-i+1,res[(p<<1)-i]);
        while(s[i-res[i]]==trs[s[i+res[i]]]) ++res[i];
        if(i+res[i]-1>mr){p=i;mr=i+res[i]-1;}
        ans+=(long long)(res[i]>>1);
      }
      printf("%lld
    ",ans);
      return 0;
    }
    
    
  • 相关阅读:
    AWT布局管理器
    聊一聊Java中的各种运算符
    Java中数组操作 java.util.Arrays 类常用方法的使用
    Python中的可变对象与不可变对象、浅拷贝与深拷贝
    【WEB基础】HTML & CSS 基础入门(7)表格
    pycaffe cifar10
    caffe 调试
    caffe Dtype
    caffe 逐步调试
    caffe template
  • 原文地址:https://www.cnblogs.com/SGCollin/p/9795534.html
Copyright © 2011-2022 走看看