其实就是复杂度是调和级数…
首先差分一下就变成了找到形如 a b a aba aba的串的个数,暴力求的话就是 n 2 l o g n n^2logn n2logn的,可以枚举 a a a的长度,然后把串分成一段一段的,只计算每段的第一个点,从第一个点 l l l找到对应的 r = l + l e n + m r=l+len+m r=l+len+m,然后看 l , r l,r l,r能同时向左右延伸到哪里,也就是后缀 l c p lcp lcp和反串后缀 l c p lcp lcp,和 l e n len len取 m i n min min,代表这个区间内长度为 l e n len len的串都是合法的串,然后答案加上两个 l c p lcp lcp的和再减去 l e n len len就好了,复杂度就是调和级数, n l o g n nlogn nlogn
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define N 100005
#define inf 0x3f3f3f3f
#define LL long long
using namespace std;
inline int rd(){
int x=0,f=1;char c=getchar();
while(c<'0' || c>'9') f=c=='-'?-1:1,c=getchar();
while(c<='9' && c>='0') x=x*10+c-'0',c=getchar();
return x*f;
}
inline int min(int x,int y){return x<y?x:y;}
int n,m,K,s[N],a[N],tot;
int sa[N],rk[N],tp[N],tax[N],h[N],st[N][20];
LL ans;
inline void rsort(){
for(int i=0;i<=m;i++) tax[i]=0;
for(int i=1;i<=n;i++) tax[rk[i]]++;
for(int i=1;i<=m;i++) tax[i]+=tax[i-1];
for(int i=n;i;i--) sa[tax[rk[tp[i]]]--]=tp[i];
}
inline void ssort(){
for(int i=1;i<=n;i++) rk[i]=s[i],tp[i]=i;
rsort();
for(int w=1,p=0;p<n&&w<=n;w<<=1,m=p){
p=0;
for(int i=n-w+1;i<=n;i++) tp[++p]=i;
for(int i=1;i<=n;i++)
if(sa[i]>w) tp[++p]=sa[i]-w;
rsort(); swap(rk,tp);
rk[sa[1]]=p=1;
for(int i=2;i<=n;i++)
if(tp[sa[i]]==tp[sa[i-1]] && tp[min(n+1,sa[i]+w)]==tp[min(n+1,sa[i-1]+w)])
rk[sa[i]]=p;
else rk[sa[i]]=++p;
}
}
inline void get_h(){
int k=0,j;
for(int i=1;i<=n;i++){
if(k) --k;
j=sa[rk[i]-1];
while(s[j+k]==s[i+k]) ++k;
h[rk[i]]=k;
}
}
inline void prework(){
for(int i=1;i<=n;i++) st[i][0]=h[i];
for(int j=1;(1<<j)<=n;j++)
for(int i=1;i+(1<<j)-1<=n;i++)
st[i][j]=min(st[i][j-1],st[i+(1<<(j-1))][j-1]);
}
inline int lcp(int l,int r){
if(l>r) swap(l,r); ++l;
int k=log2(r-l+1);
return min(st[l][k],st[r-(1<<k)+1][k]);
}
inline void solve(){
int r,len1,len2,len;
for(int i=1;i+i+K<=tot;i++)
for(int l=1;l+i+K<=tot;l+=i){
r=l+i+K;
len1=min(i,lcp(rk[l],rk[r]));
len2=min(i,lcp(rk[n-l+1],rk[n-r+1]));
if(len1+len2>=i) ans+=len1+len2-i;
}
}
int main(){
n=rd(); K=rd();
for(int i=1;i<=n;i++) s[i]=rd(); --n; tot=n;
for(int i=1;i<=n;i++) s[i]=s[i+1]-s[i],a[i]=s[i];
s[++n]=-1; a[n]=-1;
sort(a+1,a+n+1); m=unique(a+1,a+n+1)-a-1;
for(int i=tot;i;i--) s[++n]=s[i];
for(int i=1;i<=n;i++) s[i]=lower_bound(a+1,a+m+1,s[i])-a;
m=n;
ssort(); get_h(); prework();
solve();
printf("%lld\n",ans);
return 0;
}