【哈希 二分】bzoj2084: [Poi2010]Antisymmetry

8
11001011

7

hint

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

题目分析

 1 #include<bits/stdc++.h>
2 typedef unsigned long long ull;
3 const int maxn = 500035;
4 const ull base = 233;
5
6 int n;
7 char s[maxn];
8 ull power[maxn],lhsh[maxn],rhsh[maxn],ans;
9
10 bool equal(int l, int r)
11 {
12     return lhsh[r]-lhsh[l]*power[r-l]==rhsh[l]-rhsh[r]*power[r-l];
13 }
14 int main()
15 {
16     scanf("%d%s",&n,s+1);
17     power[0] = 1;
18     for (int i=1; i<=n; i++)
19         power[i] = power[i-1]*base, lhsh[i] = (lhsh[i-1]*base)+(s[i]-'0');
20     for (int i=n; i; i--)
21         rhsh[i] = (rhsh[i+1]*base)+1-(s[i]-'0');
22     for (int i=1; i<=n; i++)
23     {
24         int l = 1, r = std::min(i, n-i), pos = 0;
25         for (int mid=(l+r)>>1; l<=r; mid=(l+r)>>1)
26             if (equal(i-mid+1, mid+i)) l = mid+1, pos = mid;
27             else r = mid-1;
28         ans += pos;
29     }
30     printf("%lld\n",ans);
31     return 0;
32 }

此外还有改进的manacher做法？

 1 #include<bits/stdc++.h>
2 using namespace std;
3 const int maxx=500002;
4 int n,f[maxx],mid=1,r=1;
5 long long ans;
6 char s[maxx];
7 int main(){
8 //    freopen("x.in","r",stdin);
9     scanf("%d%s",&n,s+1);s[0]=s[n+1]='9';
10     for(int i=2;i<=n;i++){
11         if(i<r)f[i]=min(r-i+1,f[(mid<<1)-i]);else f[i]=0;
12         while(abs(s[i+f[i]]-s[i-f[i]-1])==1)++f[i];
13         if(i+f[i]-1>r)mid=i,r=i+f[i]-1;
14         ans+=f[i];
15     }
16     printf("%lld",ans);
17     return 0;
18 }copyright @MikuKnight

END

posted @ 2018-08-21 16:23  AntiQuality  阅读(244)  评论(0编辑  收藏  举报