https://codeforces.com/problemset/problem/1221/E
给定由 X
和 .
组成的字符串,先手每次可以选择长度为 \(a\) 的全 .
子串变成 X
,后手每次可以选择长度为 \(b\) 的全 .
子串变成 X
问谁必胜
\(n\le 3\times 10^5\),保证 \(a>b\)
把每个极长的全 .
子串拿出来分别考虑
若存在某子串长度在 \([b,a)\) 中,则后手必胜,考虑去除掉这个子串,若某时刻先手选完以后后手不能选了,后手就选这个长度 \([b,a)\) 的,此时轮到先手一定不能再选
现在讨论不存在长度 \([b,a)\) 的子串,那么后手一定想要通过操作得到这样的子串
若存在某子串长度在 \([2b,\infty)\) 中,那么后手可以通过一部操作得出一个长度在 \([b,a)\) 中的子串(或者说直接操作出一个长度为 \(b\) 的就行)
- 若这种子串多余一个,那么后手必胜
- 若这种子串只有一个,那么先手可以尝试挽救一下
- 不好直接讨论,于是枚举先手把这个串通过一次操作分割成了 \(p,q\),若存在 \([b,a)\) 或 \([2b,\infty)\) 长度的,必然不行,否则只剩下 \(1\) 或 \(2\) 个长度在 \([a,2b)\) 中的
- 那么再加上原来的长度在 \([a,2b)\) 中的子串,设共 \(x\) 个,这些串只能被先后获后手操作仅一次,则先手必胜当且仅当 \(x\) 奇数
- 若不存在这种子串,那么若长度在 \([a,2b)\) 中的子串有偶数个,则后手胜,否则先手胜
#define N 300006
char s[N];
int main(){int $=read();while($--){
int a=read(),b=read();read(s+1);
int n=std::strlen(s+1);
int _b=0,_ab=0,_a=0,_alen=0;
for(int i=1;i<=n;i++)if(s[i]=='.'){
int j=i;while(s[j]=='.') j++;
int len=j-i;
if(len<b);
else if(len<a) _b=1;
else if(len<b<<1) _ab++;
else _a++,_alen=len;
i=j;
}
if(_b||_a>1) write("nO\n");
else if(!_a) write((_ab&1)?"yEs\n":"nO\n");
else{
for(int p=0,q;_alen-p-a>=0;p++){
q=_alen-p-a;
if((p>=b<<1)||(q>=b<<1)) continue;
if((p>=b&&p<a)||(q>=b&&q<a)) continue;
if(!((_ab+(p>=b)+(q>=b))&1)) goto YES;
}
write("nO\n");continue;
YES:write("yEs\n");
}
}
return SUC_RETURN;
}