题目
定义字符串S为原串,SR为原串反转的到的字符串,SL为将原串中所有1变成0,0变成1得到的字符串。
一个非空字符串,对于他的每个第i个位置的字符和倒数第i个位置的字符都不同,那么这个串为antisymmetry。
特别的,如果一个字符串仅有0和1组成,那么当且仅当SL=SR的时候,他为antisymmetry。
对于一个长度为N的01串,我们需要确定这个01串中连续.非空.且满足antisymmetric的片段的数目。
不同的片段,对应相同的子串的情形也需要计数。
第一行输入一个整数N表示01串的长度
第二行输入一个长度为N的01串
40% 1<=n<=500
70% 1<=n<=5000
100% 1<=n<=500000
Output
输出一个整数表示antisymmetry串的数目
分析
根据数(xuan)学
我们可以发现对于随机数据暴力TLE的概率为
(1/2)250000
于是暴力A了
这里奉上两位dalao的写法
Orz orzgeotcbrl(hsz)
#include <cstdio>
#include <algorithm>
using namespace std;
#define N 500050
int n,i,j,p[N];
char s[N];
int main()
{
scanf("%d",&n);
scanf("%s",s);int ans=0;
for (i=1;i<n;i++){
if (j+p[j]>i) p[i]=min(j+p[j]-i,p[2*j-i]);
while (i-p[i]-1>=0&&i+p[i]<n&&s[i-p[i]-1]!=s[i+p[i]]) p[i]++;ans+=p[i];
if (i+p[i]>j+p[j]) j=i;
}printf("%d\n",ans);
return 0;
}
Orz lwn
#include <cstdio>
#include <algorithm>
#define M 1000000007
//#define M 998244353
#define DDF 2
//Deep♂Dark♂Fantasy
#define mid ((l+r+1) >> 1)
using namespace std;
int n,l,r,ans;
long long a[500050],f[500050],pre[500050],suf[500050];
char ch;
int main(){
scanf("%d",&n);
scanf("%c",&ch);
for (int i=1;i<=n;i++) scanf("%c",&ch),a[i]=ch=='0'?-1:1;
f[0]=1;
for (int i=1;i<=n;i++) f[i]=f[i-1]*DDF % M;
for (int i=1;i<=n;i++) pre[i]=(pre[i-1]+a[i]*f[i-1]) % M;
for (int i=n;i>=1;i--) suf[i]=(suf[i+1]+a[i]*f[n-i]) % M;
// for (int i=1;i<=n;i++) printf("%d ",pre[i]);printf("\n");
// for (int i=1;i<=n;i++) printf("%d ",suf[i]);printf("\n");
for (int i=1;i< n;i++){
for (l=0,r=min(i,n-i);l<r;){
long long x=((pre[i+mid] -pre[i] )*f[n-i] % M+M) % M;
long long y=((suf[i-mid+1]-suf[i+1])*f[i] % M+M) % M;
if (((x+y) % M)==0) l=mid;else r=mid-1;
}
ans+=l;
// printf("%d\n",ans);
}
printf("%d\n",ans);
return 0;
}