$n leq 30000$的字符串,问其所有子串的所有AABB形式的拆分有多少种。$t leq 10$组询问。
$n^3$过80,$n^2$过95,鬼去写正解。。
$n^2$:先枚举一次算每个位置结尾的AA形式的子串,再枚举一次用类似的方法算答案。
正解:类似,记每个位置结尾的AA的子串和每个位置开头的即可。算这个数组可用如此方法:枚举A长度$L$,每A个位置标记一个关键点。然后相邻两个关键点$a,b$,找前缀$a,b$的最长公共后缀$p$和后缀$a,b$的最长公共前缀$s$,若$p+s>L$说明这里有一些A,其中作为起点的范围是$[a-p+1,a+s-L]$,作为终点的范围$[b-p+L,b+s-1]$,相当于做了个区间加,可以差分。这样做的话,复杂度就变成$frac{n}{1}+frac{n}{2}+...=n ln n$了。
找最长公共前后缀,sa或二分hash或sam均可。
1 //#include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 //#include<math.h> 5 //#include<set> 6 //#include<queue> 7 //#include<bitset> 8 //#include<vector> 9 #include<algorithm> 10 #include<stdlib.h> 11 using namespace std; 12 13 #define LL long long 14 int qread() 15 { 16 char c; int s=0,f=1; while ((c=getchar())<'0' || c>'9') (c=='-') && (f=-1); 17 do s=s*10+c-'0'; while ((c=getchar())>='0' && c<='9'); return s*f; 18 } 19 20 //Pay attention to '-' , LL and double of qread!!!! 21 22 int T,n; 23 #define maxn 60011 24 char s[maxn]; int f[maxn],g[maxn]; 25 26 struct SAM 27 { 28 struct Node{int pre,ch[26],pos,Max;}a[maxn]; 29 int size,last; 30 void clear() 31 { 32 size=last=0; a[0].pre=-1; a[0].pos=a[0].Max=0; memset(a[0].ch,0,sizeof(a[0].ch)); 33 le=2; memset(first,0,sizeof(first)); 34 } 35 int pp[maxn]; 36 void insert(int c,int p) 37 { 38 int x=++size,y=last; memset(a[x].ch,0,sizeof(a[x].ch)); 39 a[x].Max=a[last].Max+1; a[x].pos=p; pp[p]=x; 40 last=x; 41 for (;~y && !a[y].ch[c];y=a[y].pre) a[y].ch[c]=x; 42 if (!~y) a[x].pre=0; 43 else if (a[a[y].ch[c]].Max==a[y].Max+1) a[x].pre=a[y].ch[c]; 44 else 45 { 46 int z=a[y].ch[c],w=++size; a[w]=a[z]; a[w].pos=p; a[w].Max=a[y].Max+1; 47 a[z].pre=a[x].pre=w; 48 for (;~y && a[y].ch[c]==z;y=a[y].pre) a[y].ch[c]=w; 49 } 50 } 51 struct Edge{int to,next;}edge[maxn<<1]; int first[maxn],le; 52 void in(int x,int y) {Edge &e=edge[le]; e.to=y; e.next=first[x]; first[x]=le++;} 53 int Log[maxn<<1],rmq[22][maxn<<1],dep[maxn],Time,id[maxn]; 54 void predfs(int x) 55 { 56 rmq[0][++Time]=x; id[x]=Time; 57 for (int i=first[x];i;i=edge[i].next) 58 { 59 Edge &e=edge[i]; dep[e.to]=dep[x]+1; 60 predfs(e.to); rmq[0][++Time]=x; 61 } 62 } 63 void pre() 64 { 65 for (int i=1;i<=size;i++) in(a[i].pre,i); 66 Time=0; predfs(0); 67 Log[0]=-1; for (int i=1,to=size*2-1;i<=to;i++) Log[i]=Log[i>>1]+1; 68 for (int j=1;j<=18;j++) 69 for (int i=1,to=size*2-(1<<j);i<=to;i++) 70 rmq[j][i]=dep[rmq[j-1][i]]>dep[rmq[j-1][i+(1<<(j-1))]]?rmq[j-1][i+(1<<(j-1))]:rmq[j-1][i]; 71 } 72 int qq(int x,int y) 73 { 74 x=id[pp[x]]; y=id[pp[y]]; if (x>y) x^=y^=x^=y; int l=Log[y-x+1]; 75 return a[dep[rmq[l][x]]>dep[rmq[l][y-(1<<l)+1]]?rmq[l][y-(1<<l)+1]:rmq[l][x]].Max; 76 } 77 }s1,s2; 78 //1 shi zheng de , 2 shi fan de 79 80 int main() 81 { 82 T=qread(); 83 while (T--) 84 { 85 scanf("%s",s+1); n=strlen(s+1); 86 s1.clear(); s2.clear(); 87 for (int i=1;i<=n;i++) s1.insert(s[i]-'a',i); 88 for (int i=n;i;i--) s2.insert(s[i]-'a',i); 89 s1.pre(); s2.pre(); 90 91 memset(f,0,sizeof(f)); 92 memset(g,0,sizeof(g)); 93 for (int i=1;i<=n;i++) 94 for (int j=i;j<=n-i;j+=i) 95 { 96 int k=j+i,p=s1.qq(j,k),s=s2.qq(j,k); p=min(p,i); s=min(s,i); 97 if (p+s>i) f[j-p+1]++,f[j+s-i+1]--,g[k-p+i]++,g[k+s]--; 98 } 99 100 for (int i=1,now=0;i<=n;i++) now+=f[i],f[i]=now; 101 for (int i=1,now=0;i<=n;i++) now+=g[i],g[i]=now; 102 LL ans=0; 103 for (int i=1;i<n;i++) ans+=g[i]*1ll*f[i+1]; 104 printf("%lld ",ans); 105 } 106 return 0; 107 }