题解:CF2225F String Cutting
赛时看到 E 是不可做题就去看 F 了,已经知道结论但我比较
题意:把
结论:恰分成
::::info[证明:]
假设我们分成了超过
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5,P1=998244353,P2=1e9+7,b1=1235,b2=97;
int T,n,k,l,r[N];
string s;
struct HSH{int a,b;}H[N],mi[N];
HSH operator+(HSH x,int y){x.a=(1ll*x.a*b1+y)%P1,x.b=(1ll*x.b*b2+y)%P2;return x;}
HSH operator-(HSH x,HSH y){x.a=((x.a-y.a)%P1+P1)%P1,x.b=((x.b-y.b)%P2+P2)%P2;return x;}
HSH operator*(HSH x,HSH y){x.a=1ll*x.a*y.a%P1,x.b=1ll*x.b*y.b%P2;return x;}
HSH Q(int l,int r){return H[r]-H[l-1]*mi[r-l+1];}
bool operator==(HSH x,HSH y){return x.a==y.a&&x.b==y.b;}
int check(int i){int t=min((i-1)/l+1,k);if((t!=1||i==1)&&i<=n-(k-t+1)*l+1) return n-(k-t)*l;return 0;}
bool big(int l,int r,int L,int R){
if(s[l]!=s[L]) return s[l]>s[L];
int z=1,y=min(r-l+1,R-L+1);
while(z<=y){int mid=(z+y)>>1;if(Q(l,l+mid-1)==Q(L,L+mid-1)) z=mid+1;else y=mid-1;}
if(l+y-1==r||L+y-1==R) return r-l+1>R-L+1;
return s[l+y]>s[L+y];
}void solve(){
cin>>n>>l>>k>>s,s='|'+s;
if(n<1ll*l*k){cout<<"NO\n";return;}cout<<"YES\n";
for(int i=1;i<=n;i++) r[i]=check(i),H[i]=H[i-1]+s[i];
int L=1,R=r[1];
for(int i=2;i<=n;i++)if(r[i]&&big(i,r[i],L,R)) L=i,R=r[i];
for(int i=L;i<=R;i++) cout<<s[i];cout<<'\n';
}int main(){
cin>>T,mi[0]={1,1};for(int i=1;i<N;i++) mi[i]=mi[i-1]+0;
while(T--) solve();
return 0;
}