题解:
点分治,如果点数 ≥ n \ge \sqrt{n} ≥n,则结合后缀树 O ( s z e + m ) O(sze+m) O(sze+m)处理出每个位置的开始,结束点并统计答案。否则从每个点开始暴力扩展路径。
时间复杂度 O ( n n ) O(n \sqrt{n}) O(nn)。
#include <bits/stdc++.h>
using namespace std;
typedef pair <int,int> pii;
typedef long long LL;
inline int rd() {
char ch=getchar(); int i=0,f=1;
while(!isdigit(ch)) {
if(ch=='-') f=-1; ch=getchar();}
while(isdigit(ch)) {
i=(i<<1)+(i<<3)+ch-'0'; ch=getchar();}
return i*f;
}
const int N=1e5+50, B=150;
int n,m,mx,total,G,fa[N];
int sze[N],c1[N],c2[N],vis[N];
char s[N];
long long ans;
vector <int> edge[N];
struct sam {
char ch[N];
int last,tot;
int pos[N],son[N][26],tr[N][26],fail[N],len[N];
int c[N],q[N];
vector <int> edge[N];
sam() {
last=tot=1;}
inline void extend(int c,int op) {
int p=++tot; len[p]=len[last]+1; pos[p]=op;
for(;last && !son[last][c];last=fail[last]) son[last][c]=p;
if(!last) fail[p]