题解:CF461E Appleman and a Game
考虑
由此,我们可以将
随后,根据此状态 DP 可以做到
发现
代码:
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+5;
inline long long read(){
long long x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
return x*f;
}
long long m;
int n;
char s[N];
unsigned long long ksm[N],base=13131,hsh[N];
struct matrix{
__int128 f[75][75];
inline matrix operator*(matrix b){
matrix c;
for(int i = 0;i<64;i++){
for(int j = 0;j<64;j++){
c.f[i][j]=1e30;
for(int k = 0;k<64;k++)c.f[i][j]=min(c.f[i][j],f[i][k]+b.f[k][j]);
}
}
return c;
}
}ans,f[61];
vector<int>v[5];
inline int id(int x,int y){
return x*16+y;
}
map<unsigned long long,int>mp;
int main(){
m=read();scanf("%s",s+1),n=strlen(s+1);
ksm[0]=1;
for(int i = 1;i<=n;i++){
ksm[i]=ksm[i-1]*base;hsh[i]=hsh[i-1]*base+s[i]-'A';
v[s[i]-'A'].push_back(i);
}
for(int i = 0;i<16;i++){
for(int j = 0;j<4;j++){
int len = 1,now=1;
while(1){
mp.clear();
for(int k = 0;k<4;k++){
if(!(i&(1<<k)))continue;
for(auto pos : v[k])if(pos>len && s[pos-len]==j+'A')mp[hsh[pos-1] - hsh[pos-len-1]*ksm[len]]++;
}
if(mp.size()<now)break;
len++,now*=4;
}
for(int k = 0;k<4;k++){
if(i&(1<<k)){
for(int o = 0;o<16;o++)f[0].f[id(j,i)][id(k,o)]=len;
}
else{
for(int o = 0;o<16;o++)f[0].f[id(j,i)][id(k,o)]=1e18;
}
}
}
}
for(int i = 1;i<=60;i++){
f[i]=f[i-1]*f[i-1];
}
long long res=1;
for(int i = 60;i>=0;i--){
auto now = ans*f[i];
__int128 minn=1e30;
for(int j = 0;j<64;j++)minn=min(minn,now.f[1][j]);
if(minn>=m)goto fail;
res+=(1ll<<i);ans=now;
fail:;
}
cout<<res;
return 0;
}