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;
    }
    
    
  • 相关阅读:
    CSS:在input、pre中左边加上一个图标(一行和多行)
    IntelliJ IDEA 15 创建maven项目
    IntelliJ IDEA 15 部署Tomcat及创建一个简单的Web工程
    IntelliJ IDEA 15 安装
    IntelliJ IDEA 15 设置默认浏览器
    Eclipse 创建Maven工程
    Eclipse 安装热部署JRebel
    解决无法删除表,提示被外键约束引用
    MySql创建触发器
    WinServer2008r2 机器时间格式修改
  • 原文地址:https://www.cnblogs.com/SGCollin/p/9795534.html
Copyright © 2011-2022 走看看