题解 P9873 [EC Final 2021] Beautiful String
2023/11/30 upd: 感谢 zyc212303 指出一处 typo。
貌似写了个常数比较小的做法,目前洛谷最优解 rk1 390ms,比 rk2 825ms 快了一倍。
首先由
考虑
然后考虑
时间复杂度
代码:
#include<bits/stdc++.h>
using namespace std;
//#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops")
#define ALL(v) v.begin(),v.end()
#define For(i,_) for(int i=0,i##end=_;i<i##end;++i) // [0,_)
#define FOR(i,_,__) for(int i=_,i##end=__;i<i##end;++i) // [_,__)
#define Rep(i,_) for(int i=(_)-1;i>=0;--i) // [0,_)
#define REP(i,_,__) for(int i=(__)-1,i##end=_;i>=i##end;--i) // [_,__)
typedef long long ll;
typedef unsigned long long ull;
#define V vector
#define pb push_back
#define pf push_front
#define qb pop_back
#define qf pop_front
#define eb emplace_back
typedef pair<int,int> pii;
typedef pair<ll,int> pli;
#define fi first
#define se second
const int dir[4][2]={{-1,0},{0,1},{1,0},{0,-1}},inf=0x3f3f3f3f,mod=1e9+7;
const ll infl=0x3f3f3f3f3f3f3f3fll;
template<class T>inline bool ckmin(T &x,const T &y){return x>y?x=y,1:0;}
template<class T>inline bool ckmax(T &x,const T &y){return x<y?x=y,1:0;}
int init=[](){return cin.tie(nullptr)->sync_with_stdio(false),0;}();
int main(){
int t_case=1;
cin>>t_case;
while(t_case--){
string s;
cin>>s;
ll ans=0;
int n=s.size();
V<int>lcp(n);
V<V<int>>sum(n);
Rep(i,n){
sum[i].resize(n-i-1>>1);
V<int>sum2(sum.size());
FOR(j,i+1,n){
if(s[i]==s[j]){
lcp[j]=(j+1<n?lcp[j+1]:0)+1;
if(i+lcp[j]>=j&&j-i<sum[j].size())ans+=sum[j][j-i];
if(sum[i].size()){
int ed=min(j-i-1,lcp[j]);
sum[i][0]+=ed,--sum2[0];
if(ed<sum[i].size())++sum2[ed];
}
}
else lcp[j]=0;
}
FOR(j,1,sum[i].size())sum[i][j]+=sum[i][j-1]+sum2[j-1],sum2[j]+=sum2[j-1];
}
printf("%lld\n",ans);
}
return 0;
}