Topic: Given a sequence, the number of substrings after the difference is ABA, where b part length is m,a part length is greater than 0
First enumerate the length j of a, inserting a key point at every J point in the sequence
For the key point in position I, we find the first i+j+m position
Use a suffix array to find out how many locations are the same for two positions, and the same for the right extension.
To ensure that you do not repeat left and right up to j-1 locations
After the expansion length is Len, then if len>=j,ans+= (len-j+1)
, the extended area length is 5,j=4, you can find two substrings
Where two A is the same, but because a belongs to the previous key, so in order to avoid repeated counting and no longer extend to the left
Total key points O (Nlogn) time complexity O (NLOGN)
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define M 100100using namespace Std;int n,m,a[m];int log2[m],min_height[m][18];long long ans;namespace suffix_array{int Sa[M], Rank[m],height[m];int x[m],y[m],sum[m],temp[m],tot;void Get_rank (int n) {static pair<int,int> b[M];int i;for (i= 1;i<=n;i++) B[i]=make_pair (a[i],i); sort (b+1,b+n+1); for (i=1;i<=n;i++) {if (I==1 | | b[i].first!=b[i-1].first) + + Tot;rank[b[i].second]=tot;}} void Radix_sort (int n,int key[],int order[]) {int i;for (i=0;i<=n;i++) sum[i]=0;for (i=1;i<=n;i++) sum[key[i]]++; for (i=1;i<=n;i++) sum[i]+=sum[i-1];for (i=n;i;i--) temp[sum[key[order[i]]]--]=order[i];for (i=1;i<=n;i++) Order[i]=temp[i];} void Get_height (int n) {int i,j,k;for (i=1;i<=n;i++) {if (rank[i]==1) Continue;j=max (height[rank[i-1]]-1,0); k=sa[ Rank[i]-1];while (A[i+j]==a[k+j]) ++j;height[rank[i]]=j;} void prefix_doubling (int n) {int i,j; Get_rank (n); for (j=1;j<=n;j<<=1) {for (i=1;i<=n;i++) {x[i]=rank[i];Y[i]=i+j>n?0:rank[i+j];sa[i]=i;} Radix_sort (N,Y,SA); Radix_sort (N,X,SA); for (tot=0,i=1;i<=n;i++) {if (I==1 | | X[sa[i]]!=x[sa[i-1] | | Y[SA[I]]!=Y[SA[I-1]]) ++tot;rank[sa[i]]=tot;}} Get_height (n);}} int min_height (int x,int y) {if (x>y) swap (x, y), int len=log2[y-(++x) +1];return Min (min_height[x][len],min_height[y- (1<<len) +1][len]);} int main () {using namespace Suffix_array;int I,j;cin>>n>>m;memset (a,0xef,sizeof a); for (i=1;i<=n;i++) scanf ("%d", &a[i]); for (n--, i=1;i<=n;i++) a[i]=a[i+1]-a[i];a[n+1]=19980402;for (i=n;i;i--) a[n+n+2-i]=a[i]; Prefix_doubling (n+n+1); for (log2[0]=-1,i=1;i<=n+n+1;i++) log2[i]=log2[i>>1]+1;for (i=1;i<=n+n+1;i++) Min_height[i][0]=height[i];for (j=1;j<=log2[n+n+1];j++) for (i=1;i+ (1<<j) -1<=n+n+1;i++) min_height[i][ J]=min (min_height[i][j-1],min_height[i+ (1<<j-1)][j-1]); for (j=1;j+j+m<=n;j++) {int last=0;for (i=1;i+j+m <=N;I+=J) {int temp=min_height (rank[i],rank[i+j+m]); Temp=min (temp,j); if (last+temp>=j) ans+=last+temp-j+1;Last=min_height (rank[(n+n+2)-(i+j-1)],rank[(n+n+2)-(i+j+j+m-1)]); Last=min (last,j-1);}} Cout<<ans<<endl;return 0;}
BZOJ 2119 forecast suffix array for the stock market