BZOJ2084 POI2010 Antisymmetry
来源:互联网 发布:网店美工是什么专业 编辑:程序博客网 时间:2024/05/29 18:38
POI2010 题解整理
Description
对于一个01字符串,如果将这个字符串0和1取反后,再将整个串反过来和原串一样,就称作“反对称”字符串。比如00001111和010101就是反对称的,1001就不是。
现在给出一个长度为N的01字符串,求它有多少个子串是反对称的。
Input
- 第一行一个正整数
N (N≤5∗105) 。- 第二行一个长度为
N 的01字符串。Output
- 一个正整数,表示反对称子串的个数。
Sample Input
8
11001011Sample Output
7
很显然,本题重点在于如何优化以前的
回忆以前的做法,我们是枚举中心点,再
那么找完半径后,如何快速判断左右两段是对称的?我们可以采用Hash来代替通过枚举判断回文的复杂度。于是此题
#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define B 200019#define M 500005#define P 1000000009using namespace std;int n,Base[M],Hnxt[M],Hback[M];char str[M];void init(){ scanf("%d %s",&n,str+1); Base[0]=1;for(int i=1;i<=n;i++)Base[i]=1LL*Base[i-1]*B%P; Hnxt[0]=0;for(int i=1;i<=n;i++)Hnxt[i]=(1LL*Hnxt[i-1]*B+str[i])%P; Hback[n+1]=0;for(int i=n;i>=1;i--)Hback[i]=(1LL*Hback[i+1]*B+(str[i]^'0'^1^'0'))%P;}int Hashnxt(int L,int R){ int ans=Hnxt[R]-1LL*Hnxt[L-1]*Base[R-L+1]%P; if(ans<0)ans+=P; return ans;}int Hashback(int L,int R){ int ans=Hback[L]-1LL*Hback[R+1]*Base[R-L+1]%P; if(ans<0)ans+=P; return ans;}int main(){ init(); long long ans=0; for(int pos=1;pos<n;pos++){//对称轴的位置在[pos,pos+1]内 int L=1,R=min(pos,n-pos),res=0; while(L<=R){ int mid=L+R>>1; if(Hashnxt(pos-mid+1,pos+mid)==Hashback(pos-mid+1,pos+mid)) res=mid,L=mid+1; else R=mid-1; } ans+=res; } cout<<ans<<endl;}
还有一种解法,就是利用Manacher算法在
- 在回文串对称点左侧出现的小回文串,必然在右侧也会出现。
那么每次出发时,如果已经有小回文串作为基础,就不需要从r=0再枚举一遍。
还有一个问题——为什么只是简化了枚举,复杂度却达到了我觉得还没讲清楚,当历史遗留问题好了)
#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define M 500005using namespace std;char str[M],buf[M<<1],tmp[M<<1];int p[M<<1];int main(){ int n; scanf("%d",&n); scanf("%s",str); for(int i=0;i<=n;i++)buf[i<<1]=tmp[i<<1]='#'; for(int i=0;i<n;i++)buf[i<<1|1]=str[i],tmp[i<<1|1]=str[i]^'0'^1^'0'; n<<=1; int id=0,mx=0; long long ans=0; for(int i=1;i<n;i++){ if(mx>i)p[i]=min(p[id*2-i],mx-i); while(i-p[i]>=0&&buf[i-p[i]]==tmp[i+p[i]])++p[i]; if(i+p[i]>mx)mx=i+p[i],id=i; if(buf[i]=='#')ans+=p[i]>>1; } cout<<ans<<endl;}
0 0
- 【bzoj2084】 POI2010 Antisymmetry manacher
- 【bzoj2084】【poi2010】【Antisymmetry】【manacher】
- [BZOJ2084] [Poi2010]Antisymmetry
- bzoj2084【POI2010】Antisymmetry
- 【BZOJ2084】[Poi2010]Antisymmetry【Manacher】
- BZOJ2084[Poi2010] Antisymmetry
- BZOJ2084 POI2010 Antisymmetry
- BZOJ2084: [Poi2010]Antisymmetry
- bzoj2084【POI2010】Antisymmetry manacher
- 【bzoj2084】 [Poi2010]Antisymmetry
- 【bzoj2084】[Poi2010]Antisymmetry
- bzoj2084 [Poi2010]Antisymmetry
- Bzoj2084:[Poi2010]Antisymmetry:manachar算法
- BZOJ2084: [Poi2010]Antisymmetry manacher算法
- [BZOJ2084][Poi2010]Antisymmetry(hash+二分||manacher)
- [bzoj2084][POI2010]ANT-Antisymmetry(二分+hash)
- POI2010 Antisymmetry
- [Poi2010]Antisymmetry
- NGUI easytouch Drag事件处理
- 05 初始化与清理
- 使用脚本遍历子目录
- tensorflow- MNIST机器学习入门
- 关于clientHeight、offsetHeight 和 scrollHeight
- BZOJ2084 POI2010 Antisymmetry
- Ubuntu安装JDK详解
- P1034 矩形覆盖
- Java 分层概念
- Java二叉树的实现(链式实现)
- hdu 5074 Hatsune Miku【DP】
- jdk 与jre 的区别
- 母函数练习2
- 多关键字排序 shell 为什么就不对呢