• [POI2010]ANT-Antisymmetry


    [POI2010]ANT-Antisymmetry

    题意:给你一个长度为(n)(01)串,求它的非空并在异或意义下回文的子串数。

    这里我们介绍马拉车的扩展:

    引入(to)数组,表示每个字符与哪个字符匹配。

    例如,在模板题中,有(forall c in ['a','z'],to_c=c)

    而在这道题中,有(to_{'1'}='0',to_{'0'}='1')

    并且我们令(to[)#(]=[)#(])

    然后就可以匹配了。

    注意!!这个时候初始回文串长度应为(0),因为自己不一定与自己相配。

    即:

    rad[i]=(i<Rpos)?min(Rpos-i,rad[Centre*2-i]):0;
    

    最后是(0)不是(1)

    另,统计答案时应是:

    Ans+=(rad[i]>>1);
    

    因为加入了辅助字符 # ,所以数量要减半。

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define int long long
    int S,rad[1001000],Rpos,Centre,Ans;
    char s[1001000],to[129];
    void getln(){
    	char c=getchar();
    	to['0']='1',to['1']='0',to['$']='$';
    	s[0]='$',S=1;
    	while(c!='0'&&c!='1')c=getchar();
    	while(c=='0'||c=='1')s[S++]=c,s[S++]='$',c=getchar();
    	s[S]='';
    }
    void Manacher(){
    	Rpos=Centre=-1;
    	for(int i=0;i<S;i++){
    		rad[i]=(i<Rpos)?min(Rpos-i,rad[Centre*2-i]):0;
    		while(i-rad[i]>=0&&i+rad[i]<S)if(to[s[i-rad[i]]]==s[i+rad[i]])rad[i]++;else break;
    		if(i+rad[i]>Rpos)Rpos=i+rad[i],Centre=i;
    		Ans+=(rad[i]>>1);
    	}
    }
    signed main(){
    	scanf("%lld",&S);
    	getln();
    	Manacher();
    	printf("%lld",Ans);
    	return 0;
    }
    
  • 相关阅读:
    存储过程学习笔记
    重新学习struts
    ANT打包J2EE项目war包
    08 | 递归:如何用三行代码找到“最终推荐人”?
    基于Flask 实现Web微信登陆
    基于轮询实现实时的在线投票系统
    Flask 微信公众号开发
    微信公众号开发
    爬虫之正则案例
    爬虫之正则表达式的应用爬取
  • 原文地址:https://www.cnblogs.com/Troverld/p/12772339.html
Copyright © 2020-2023  润新知