自己de了一天,现在的结果是,可以确定后缀排序后有的rk重复了,数据点4的第3个数据排完后rk[1] = rk[4] = 26,但是我一直每整明白为什么,请dalao指教!这是那个数据点:
10
vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
dvdvdvdvdvdvdvdvdvdvdvdvdv
jhyjhyjhyjhyjhyjhyjhyjhyjhy
dkbjdkbjdkbjdkbjdkbjdkbjdkbjdkbj
ezlbtezlbtezlbtezlbtezlbtezlbtezlbtezlbt
efwduoefwduoefwduoefwduoefwduoefwduoefwduo
eqgdlgxeqgdlgxeqgdlgxeqgdlgxeqgdlgxeqgdlgx
mwuoqleamwuoqleamwuoqleamwuoqlea
gwcbhodfpgwcbhodfpgwcbhodfpgwcbhodfp
vprveevprveevprveevprvee
而且神奇的是,我只要把第三个串和第四个串的顺序换一下,就不会RE,而且甚至答案还是对的
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<vector>
#include<map>
#include<queue>
#include<algorithm>
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define per(i,a,b) for(int i=b;i>=a;--i)
using namespace std;
inline double fread(){
double t; scanf("%lf", &t); return t;
}
inline ll read()
{
ll x=0,f=1;
char c=getchar();
while (c<'0' || c>'9')
{
if (c=='-') f=-1;
c=getchar();
}
while (c>='0' && c<='9')
{
x=x*10+c-'0';
c=getchar();
}
return x*f;
}
inline void print(ll x)
{
if(x < 0) putchar('-'), x = -x;
if(x > 9) print(x / 10);
putchar(x % 10 + '0');
return ;
}
inline void pprint(ll x)
{
print(x); puts("");
}
inline void cprint(char *s, ll x)
{
printf("%s: %d\n", s, x);
}
inline void kprint(ll x)
{
print(x); putchar(' ');
}
inline void fpprint(double x){
printf("%lf\n", x);
}
inline void fkprint(double x){
printf("%lf ", x);
}
const int N = 5e4 + 7;
int rk[N << 1], sa[N], n, lstrk[N << 1], lstsa[N], w, m = 127, cnt[N], h[N], f1[N][20], f2[N][20], beg[N], ed[N], lrk[N << 1];
char s[N];
#define siz n * sizeof(int)
void init(){
memset(cnt, 0, sizeof cnt);
memset(sa, 0, sizeof sa);
memset(rk, 0, sizeof rk);
memset(h, 0, sizeof h);
m = 200;//init在这个地方!
// printf("%s\n", s + 1);
for(int i = 1; i <= n; ++i) ++cnt[rk[i] = s[i]];
for(int i = 1; i <= m; ++i) cnt[i] += cnt[i - 1];
for(int i = n; i >= 1; --i) sa[cnt[rk[i]]--] = i;
memcpy(lstrk + 1, rk + 1, siz);
for(int p = 0, i = 1; i <= n; ++i)
if(lstrk[sa[i]] == lstrk[sa[i - 1]])
rk[sa[i]] = p;
else
rk[sa[i]] = ++p;
for(w = 1; w < n; w <<= 1, m = n){
for(int p = 0, i = n; i >= n - w + 1; --i) lstsa[++p] = i;
for(int p = w, i = 1; i <= n; ++i)
if(sa[i] > w) lstsa[++p] = sa[i] - w;
memset(cnt, 0, sizeof cnt);
for(int i = 1; i <= n; ++i) ++cnt[rk[lstsa[i]]];
for(int i = 1; i <= m; ++i) cnt[i] += cnt[i - 1];
for(int i = n; i >= 1; --i) sa[cnt[rk[lstsa[i]]]--] = lstsa[i];
memcpy(lstrk + 1, rk + 1, siz);
for(int p = 0, i = 1; i <= n; ++i)
if(lstrk[sa[i]] == lstrk[sa[i - 1]] && lstrk[sa[i] + w] == lstrk[sa[i - 1] + w])
rk[sa[i]] = p;
else
rk[sa[i]] = ++p;
}
// rk[sa[n]] = n;
for(int i = 1, k = 0; i <= n; ++i){
if(rk[i] == 0) continue;
if(k) --k;
while(s[i + k] == s[sa[rk[i] - 1] + k]) ++k;
h[rk[i]] = k;
}
}
void init1(){
memset(f1, 0x7f, sizeof f1);
for(int i = 1; i <= n; ++i)
f1[i][0] = h[i];
for(int j = 1; (1 << j) <= n; ++j)
for(int i = 1; i <= n; ++i)
f1[i][j] = min(f1[i][j - 1], f1[i + (1 << (j - 1))][j - 1]);
}
void init2(){
memset(f2, 0x7f, sizeof f2);
for(int i = 1; i <= n; ++i)
f2[i][0] = h[i];
for(int j = 1; (1 << j) <= n; ++j)
for(int i = 1; i <= n; ++i)
f2[i][j] = min(f2[i][j - 1], f2[i + (1 << (j - 1))][j - 1]);
}
int lcp(int x, int y){
if(x > y) swap(x, y);
x++;
int k;
k = log2(y - x + 1);
return min(f1[x][k], f1[y - (1 << k) + 1][k]);
}
int lcs(int x, int y){
if(x > y) swap(x, y);
x ++;
int k;
k = log2(y - x + 1);
return min(f2[x][k], f2[y - (1 << k) + 1][k]);
}
//区间修改
void ch(int *a, int st, int wid){
a[st]++;
a[st + wid]--;
}
int main(){
int T = read();
while(T--){
memset(beg, 0, sizeof beg);
memset(ed, 0, sizeof ed);
scanf("%s", s + 1);
n = strlen(s + 1);
init();
init1();
// cout << "complete 1" << endl;
reverse(&s[1], &s[n + 1]);
// for(int i = 1; i <= n / 2; ++i)
// swap(s[i], s[n - i + 1]);
// printf("%s\n", s + 1);
memcpy(lrk + 1, rk + 1, siz);
init();
init2();
// cout << "complete 2" << endl;
// cout << "check:" << lcp(4, 6) << endl;
// cout << lrk[1] << " " << lrk[2] << endl;
// cout << lcp(1, 2) << endl;
for(int len = 1; len <= n / 2; ++len){
// cout << len << endl;
for(int j = 1; (j + 1) * len <= n; ++j){
int l = j * len, r = (j + 1) * len;
int pre = min(len, lcs(rk[n - r + 1], rk[n - l + 1]));
int nxt = min(len, lcp(lrk[l], lrk[r]));
if(pre + nxt < len + 1) continue;
int prel = l - pre + 1, edr = r + nxt - 1;
int wid = (l + nxt - 1) - (r - pre + 1) + 1 + 1;
beg[prel]++; beg[prel + wid]--;
ed[edr + 1]--; ed[edr - wid + 1]++;
}
}
for(int i = 1; i <= n; ++i)
beg[i] += beg[i - 1];
for(int i = 1; i <= n; ++i)
ed[i] += ed[i - 1];
// for(int i = 1; i <= n; ++i)
// cout << beg[i] << " "; puts("");
// for(int i = 1; i <= n; ++i)
// cout << ed[i] << " "; puts("");
// cout << "!" << endl;
ll ans = 0;
for(int i = 1; i < n; ++i){
ans += ed[i] * beg[i + 1];
}
// puts("ans = ");
pprint(ans);
}
return 0;
}