思路是设f(i,j,cur)为在区间[l,r]内,cur是否能胜出,则cur的对手一定一个来自cur所在的一半区间,另一个来自另一个区间,选择cur能打过的a最大的对手晋级,继续递归。能过讨论区的卡贪心数据。哪儿有问题呢?
#include <bits/stdc++.h>
using namespace std;
int m,k,a[(1<<18)+5];
bool dfs(int l,int r,int cur)
{
int p = (l+r)/2;
/*if(l+1 == r)
{
if(cur == l && a[cur]+m >= a[r]) return true;
if(cur == r && a[cur]+m >= a[l]) return true;
return false;
}*/
if(l == r) return true;
if(cur <= p)
{
int maxn[2],ok = 0;
\\maxn[0]是最大值大小,maxn[1]是下标
maxn[0] = maxn[1] = 0;
for(int i = p+1;i <= r;i++)
{
if(i == cur) continue;
if(a[cur]+m >= a[i] && a[i] >= maxn[0]) maxn[0] = a[i],maxn[1] = i,ok = 1;
}
if(!ok) return false;
if(dfs(l,p,cur) && dfs(p+1,r,maxn[1])) return true;
else return false;
}
else
{
int maxn[2],ok = 0;
maxn[0] = maxn[1] = 0;
for(int i = l;i <= p;i++)
{
if(i == cur) continue;
if(a[cur]+m >= a[i] && a[i] >= maxn[0]) {maxn[0] = a[i],maxn[1] = i,ok = 1;}
}
if(!ok) return false;
if(dfs(p+1,r,cur) && dfs(l,p,maxn[1])) return true;
else return false;
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int t; cin >> t;
while(t--)
{
cin >> k >> m;
for(int i = 1;i <= (1<<k);i++) cin >> a[i];
if(k == 0) {cout << "Kotori\n"; continue;}
if(dfs(1,(1<<k),1)) cout << "Kotori\n";
else cout << "Yoshino\n";
//cout << dfs(5,8,8);
}
return 0;
}