题解:P16600 [SYSUCPC 2025] Perfect Life
lailai0916 · · 题解
题意简述
给定字符串
解题思路
设
把一次操作视为一个长度为
当
这三个条件也足以构造操作顺序。扫描相邻窗口时,最大优先级区间只有三种变化。它可以继续保留、被新加入的区间替代,或在离开窗口后露出剩余区间的最大值。反向分配这些区间的优先级,即可得到指定标签序列。两个哨兵保证所有非零标签都来自完整落在
从两端向中间处理。处理完外侧
加入左侧位置时,新标签
右侧向左加入位置。设左侧转移后的位集为
预处理每个字符在
若 unsigned long long,因为共有
每对位置枚举
参考代码
#include <bits/stdc++.h>
using namespace std;
using ull=unsigned long long;
const int K=65;
ull reach(int x,int m)
{
if(x==m)return (1ULL<<(m+1))-1;
ull y=1ULL<<1;
if(x==0)y|=1;
else y|=1ULL<<(x+1);
return y;
}
bool solve(const string &s,const string &t)
{
int n=s.size(),m=t.size();
ull f[2][K]={};
ull bit[128]={};
for(int i=1;i<=m;i++)bit[(int)t[i-1]]|=1ULL<<i;
f[0][0]=1;
int cur=0;
ull tot=1;
for(int i=0;i<n/2;i++)
{
int nxt=cur^1;
ull tmp=0;
for(int j=0;j<=m;j++)
{
ull x;
if(j==0)x=f[cur][0]|f[cur][m];
else if(j==1)x=tot;
else x=f[cur][j-1]|f[cur][m];
ull y=x>>1;
if(x&2)y|=(1ULL<<m)-1;
if(x&1)y|=1;
if(x)y|=1ULL<<m;
char ch=j==0?s[i]:t[j-1];
ull ok=bit[(int)ch];
if(ch==s[n-i-1])ok|=1;
f[nxt][j]=y;
f[nxt][j]&=ok;
tmp|=f[nxt][j];
}
cur=nxt;
tot=tmp;
}
if(n%2==0)
{
for(int j=0;j<=m;j++)if(f[cur][j]&reach(j,m))return 1;
return 0;
}
ull all=(1ULL<<(m+1))-1;
for(int j=0;j<=m;j++)
{
ull x;
if(j==m)x=all;
else if(j==0)x=reach(0,m)|reach(1,m);
else x=reach(1,m)|reach(j+1,m);
if(f[cur][j]&x)return 1;
}
return 0;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
cin>>t;
while(t--)
{
string s,p;
cin>>s>>p;
cout<<(solve(s,p)?"Yes":"No")<<'\n';
}
return 0;
}