# [BZOJ2084][Poi2010]Antisymmetry 二分+hash

## 2084: [Poi2010]Antisymmetry

Time Limit: 10 Sec  Memory Limit: 259 MB
Submit: 812  Solved: 503
[Submit][Status][Discuss]

8
11001011

## Sample Output

7

hint
7个反对称子串分别是：01(出现两次), 10(出现两次), 0101, 1100和001011

## Source

 1 #include<iostream>
2 #include<cstring>
3 #include<cstdio>
4 #include<cstdlib>
5 #include<cmath>
6 #include<algorithm>
7 #define mod 100000007LL
8 using namespace std;
9 int n;
10 long long bit[500005];
11 long long b[500005],a[500005];
12 char s[500005];
13 int ans;
14 bool check(int st,int mid) {
15     if(st+mid-1>n) return 0;
16     if(st-mid<1) return 0;
17     long long x1=((b[st+mid-1]-b[st-1]*bit[mid])%mod+mod)%mod;
18     long long x2=((a[st-mid]-a[st]*bit[mid])%mod+mod)%mod;
19     return x1==x2;
20 }
21 int main() {
22     scanf("%d",&n);
23     bit[0]=1;
24     for(int i=1;i<=n;i++) {bit[i]=bit[i-1]*97%mod;}
25     scanf("%s",s+1);
26     for(int i=1;i<=n;i++) {
27         b[i]=b[i-1]*97+s[i]-'0'+1;b[i]%=mod;
28     }
29     for(int i=n;i>=1;i--) {
30         a[i]=a[i+1]*97+(((s[i]-'0')^1)+1);a[i]%=mod;
31     }
32     for(int i=1;i<=n;i++) {
33         int l=1,r=n;
34         while(l<=r) {
35             int mid=(l+r)>>1;
36             if(check(i,mid)) l=mid+1;
37             else r=mid-1;
38         }
39         ans+=(l-1);
40     }
41     printf("%d",ans);
42 }
View Code

O(∩_∩)O~ (*^__^*) 嘻嘻…… O(∩_∩)O哈哈~
posted @ 2017-10-24 15:46  wls001  阅读(158)  评论(0编辑  收藏  举报