1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
| #include <bits/stdc++.h>
using namespace std; #define LL long long #define ULL unsigned long long #define Pair pair<LL ,LL > #define ls rt<<1 #define rs rt<<1|1 #define PI acos(-1.0) #define eps 1e-12 #define mod 1000000009 #define MAXN 9e18 #define MS 500005 #define tm first #define val second
int n,m; char s[MS]; int d1[MS]; int a[MS]; struct node{ int l,r; LL cnt; }p[MS<<5]; int rtpos[MS], tot;
void manacher() { for (int i = 0, l = 0, r = -1; i < n; i++) { int k = (i > r) ? 1 : min(d1[l + r - i], r - i + 1); while (0 <= i - k && i + k < n && s[i - k] == s[i + k]) { k++; } d1[i] = k--; if (i + k > r) { l = i - k; r = i + k; } } }
int update(int lart,int l,int r,int pos){ int rt = ++tot; p[rt] = p[lart]; p[rt].cnt++; if(l == r) return rt; int m = l+r>>1; if(m >= pos) p[rt].l = update(p[lart].l,l,m,pos); else p[rt].r = update(p[lart].r,m+1,r,pos); return rt; }
LL query(int L,int R,int l,int r,LL val){ if(l == r){ if(l <= val) return p[R].cnt - p[L].cnt; return 0; } int m = l+r>>1; if(m >= val) return query(p[L].l,p[R].l,l,m,val); else return query(p[L].r,p[R].r,m+1,r,val) + p[p[R].l].cnt - p[p[L].l].cnt; }
void clear(){ tot = 0; }
void solve() { cin >> s; n = strlen(s); manacher(); for(int i=n;i>=1;i--) d1[i] = d1[i-1];
for(int i=1;i<=n;i++){ a[i] = i-d1[i]+1; } for(int i=1;i<=n;i++){ rtpos[i] = update(rtpos[i-1],1,n,a[i]); } LL ans = 0; for(int i=1;i<=n;i++){ int l = i+1, r = i+d1[i]-1; if(l > r) continue; ans += query(rtpos[l-1],rtpos[r],1,n,i); } cout << ans << "\n"; clear(); }
int main() { ios::sync_with_stdio(false); LL ce = 1; cin >> ce;
while(ce--) { solve(); }
return 0; }
|