[BZOJ2084]Antisymmetry(二分+hash)
2017-05-12 18:24
274 查看
=== ===
这里放传送门=== ===
题解
首先用【看数据范围猜复杂度大法】可以看出它的时间复杂度大概是O(nlogn)的。。。。然后它要统计的是符合条件的子串个数。一般统计子串的话都是枚举一个什么东西然后算它的贡献?比如枚举一个后缀,然后算这个后缀贡献了多少个合法的子串之类的?
这个题的话因为它有一个比较明显的类似回文的性质,所以可以考虑枚举回文中心然后计算每个点的贡献。如何在O(logn)或者类似的时间里计算每个回文中心的贡献呢。。。
回文串有一个比较重要的性质就是它的单调性,就是说一个回文中心如果往两边延伸k个字符能构成一个回文串,那么往两边延伸1..k-1个字符也是可以构成回文串的。
可以发现这个题的“反对称”也是满足这个单调性的,那么就可以二分每一个回文中心的贡献了。
判定的时候使用hash,就是把正串S和取反后倒置的反串T都搞出来然后算出要求的那一段的hash值比较是否相等就可以了。
代码
#include<cstdio> #include<cstring> #include<algorithm> #define ULL unsigned long long using namespace std; const ULL wer=2000001001; int n; long long ans; char st[500010]; ULL hash[500010],rhash[500010],mul[500010]; bool same(int s1,int s2,int len){ int t1,t2,dlt; ULL h1,h2; t1=s1+len-1;t2=s2+len-1; h1=hash[t1]-hash[s1-1]; h2=rhash[t2]-rhash[s2-1]; if (s1>s2){swap(s1,s2);swap(h1,h2);} h1*=mul[s2-s1]; return h1==h2; } long long divide(int s1,int s2,int l,int r){ int mid,ans=0; while (l<=r){ mid=(l+r)>>1; if (same(s1,s2,mid)){ ans=max(ans,mid);l=mid+1; }else r=mid-1; } return ans; } int main() { scanf("%d\n",&n); gets(st); mul[0]=1; for (int i=1;i<=n;i++) mul[i]=mul[i-1]*wer; for (int i=1;i<=n;i++) hash[i]=hash[i-1]+st[i-1]*mul[i]; for (int i=1;i<=n/2;i++) swap(st[i-1],st[n-i]); for (int i=1;i<=n;i++) if (st[i-1]=='0') st[i-1]='1'; else st[i-1]='0'; for (int i=1;i<=n;i++) rhash[i]=rhash[i-1]+st[i-1]*mul[i]; for (int i=2;i<=n;i++){ int j=n-i+1+1,len; len=min(n-i+1,n-j+1); ans+=divide(i,j,1,len); } printf("%I64d\n",ans); return 0; }
相关文章推荐
- [BZOJ2084][Poi2010]Antisymmetry(hash+二分||manacher)
- [bzoj2084][POI2010]ANT-Antisymmetry(二分+hash)
- bzoj 2084: [Poi2010]Antisymmetry (hash+二分)
- BZOJ 2084 二分+hash OR Manacher
- [BZOJ2084][Poi2010]Antisymmetry 二分+hash
- 【二分答案】【字符串哈希】bzoj2084 [Poi2010]Antisymmetry
- 【二分答案+智障的字符串hash】BZOJ2946-[Poi2000]公共串(Ranklist倒一达成!!!!!)【含hash知识点】
- 【bzoj2084】 [Poi2010]Antisymmetry
- bzoj1717[Usaco2006 Dec]Milk Patterns 产奶的模式 (二分+hash)题解①
- BZOJ[1567][JSOI2008]Blue Mary的战役地图 二分+Hash
- BZOJ 1014 火星人 prefix (splay hash 二分答案)
- 【bzoj2084】[Poi2010]Antisymmetry
- 【bzoj3796】Mushroom追妹纸 Kmp+二分+Hash
- 【BZOJ3796】Mushroom追妹纸 二分+hash
- bzoj 1567: [JSOI2008]Blue Mary的战役地图 (二分+hash)
- 【二分+map或Hash】bzoj 1567 战役地图
- 【BZOJ】1014: [JSOI2008]火星人prefix(splay+hash+二分+lcp)
- BZOJ 1014 Splay , 二分, 区间Hash
- [BZOJ1014][JSOI2008]火星人prefix splay+二分+hash
- 【BZOJ1014】【JSOI2008】火星人prefix Splay处理区间,hash+dichotomy(二分)check出解