zoukankan      html  css  js  c++  java
  • 【[POI2010]ANT-Antisymmetry】

    开始复习字符串了

    第一步肯定得是(hash)

    首先理性分析一波不可能出现长度为奇数的反回文串,对称轴位置取反之后肯定和原来不相等了

    我们可以枚举所有回文串的对称中心,之后我们发现这个样子是具有单调性de

    于是我们就利用(hash)来判断

    将原来的串取反之后在反转,判断在对称中心左右两边二分的长度是否相等就可以啦

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define re register
    #define ull unsigned long long
    #define maxn 500005
    #define min(a,b) ((a)<(b)?(a):(b))
    char S[maxn],T[maxn];
    int a[maxn],b[maxn];
    int n;
    ull ha[maxn],sh[maxn];
    ull pow[maxn];
    ull base=17;
    long long num;
    inline ull get_hash(int l,int r,int op)
    {
    	if(!op) return ha[r]-ha[l-1]*pow[r-l+1];
    	return sh[n-l+1]-sh[n-r]*pow[r-l+1];
    }
    int main()
    {
    	scanf("%d",&n);
    	scanf("%s",S+1);
    	for(re int i=1;i<=n;i++)
    		if(S[i]=='0') a[i]=0;
    			else a[i]=1;
    	pow[0]=1;
    	for(re int i=1;i<=n;i++)
    		pow[i]=pow[i-1]*base;
    	for(re int i=1;i<=n;i++)
    		ha[i]=ha[i-1]*base+(a[i]+1);
    	for(re int i=1;i<=n;i++)
    		b[i]=a[n-i+1]^1;
    	for(re int i=1;i<=n;i++)
    		sh[i]=sh[i-1]*base+(b[i]+1);
    	for(re int i=1;i<n;i++)
    	{
    		int l=1,r=min(i,n-i);
    		int ans=0;
    		while(l<=r)
    		{
    			int mid=l+r>>1;
    			if(get_hash(i-mid+1,i,1)==get_hash(i+1,i+mid,0)) l=mid+1,ans=mid;
    			else r=mid-1;
    		}
    		num+=ans;
    	}
    	printf("%lld
    ",num);
    	return 0;
    }
    /*
    8
    11001011
    */
    
  • 相关阅读:
    C# DES加密和解密
    SQL设计技巧优化
    MS15-034漏洞技术研究
    Vustudy靶场环境快速搭建
    FastJson<=1.2.47漏洞复现
    多台电脑共享一套鼠键--Mouse Without Borders
    {Java初级系列四}---继承、接口和抽象类
    {Java初级系列三}---面向对象和类
    {Java初级系列二}---Java类基础知识
    {Java初阶系列一}---Java基本简介
  • 原文地址:https://www.cnblogs.com/asuldb/p/10206178.html
Copyright © 2011-2022 走看看