题解:P15650 [省选联考 2026] 摩卡串 / string
简单赛时做法。
令
考虑如何判定一个串
我们注意到
而对于
然后每次在最后插入一个字符的时候我们会将
因此我们只需要记录当前匹配到的
这样就得到了一个一共有
然后我们就得到了一个简单的
但是这个做法看起来非常卡不满,我们来分析一下它的复杂度。
我们发现,如果
#include<bits/stdc++.h>
using namespace std;
int n,m;
queue<int> q;
struct node{
int x,y,z;bool w;
int fa;
};
vector<node> Q;
bitset<3001> vis[2][201][82];
char s[209];
int f[209],g[209];
int fa[209],ch[209][2];
void dfs(int id){
if(!id)return;
dfs(Q[id].fa);
node tmp=Q[Q[id].fa];
int x=tmp.x,y=tmp.y,z=tmp.z;bool w=tmp.w;
node t=Q[id];
int xx=ch[x][0],yy=y+g[x],zz=z+(f[xx]-(xx==n))+yy;
bool ww=w||(xx==n);
if(xx==t.x&&yy==t.y&&zz==t.z&&ww==t.w){
cout<<0;
}
else cout<<1;
}
void solve(){
cin>>n>>m>>(s+1);
int M=0;while(M*(M+1)/2<=m)++M;
for(int i=0;i<=n;i++)fa[i]=f[i]=g[i]=ch[i][0]=ch[i][1]=0;
for(int i=1;i<=n;i++)ch[i-1][s[i]-'0']=i;
for(int i=0;i<2;i++)if(ch[0][i])q.push(ch[0][i]);
while(!q.empty()){
int u=q.front();q.pop();
for(int i=0;i<2;i++){
if(ch[u][i]){
fa[ch[u][i]]=ch[fa[u]][i];
q.push(ch[u][i]);
}
else{
ch[u][i]=ch[fa[u]][i];
}
}
}
for(int i=0;i<=n;i++){
for(int j=1;j<=i;j++){
int len=i-j+1;bool flag=1;
for(int t=1;t<=len&&flag;t++){
if(s[j+t-1]!=s[t])flag=0;
}
if(flag)f[i]++;
if(s[len+1]>'0'&&flag)g[i]++;
}
g[i]+=(s[1]=='1');
}
Q.clear();
for(int i=0;i<=n;i++){
for(int j=0;j<=M;j++)vis[0][i][j].reset(),vis[1][i][j].reset();
}
Q.push_back(node{0,0,0,0,0});int head=0;
vis[0][0][0][0]=1;
while(head<Q.size()){
node tmp=Q[head];++head;
int x=tmp.x,y=tmp.y,z=tmp.z;
bool w=tmp.w;
{
int xx=ch[x][0],yy=y+g[x],zz=z+(f[xx]-(xx==n))+yy;
bool ww=w||(xx==n);
if(zz==m&&ww==1){
dfs(head-1);cout<<0<<"\n";return;
}
if(yy+zz<=m){
if(!vis[ww][xx][yy][zz]){
vis[ww][xx][yy][zz]=1;
Q.push_back(node{xx,yy,zz,ww,head-1});
}
}
}
{
int xx=ch[x][1],yy=y,zz=z+(f[xx]-(xx==n))+yy;
bool ww=w||(xx==n);
if(zz==m&&ww==1){
dfs(head-1);cout<<1<<"\n";return;
}
if(yy+zz<=m){
if(!vis[ww][xx][yy][zz]){
vis[ww][xx][yy][zz]=1;
Q.push_back(node{xx,yy,zz,ww,head-1});
}
}
}
}
cout<<"Impossible\n";
}
int main(){
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int C,T;cin>>C>>T;while(T--)solve();return 0;
}