//Finding Sprague-Grundy number for each subset of the array and finding the answer
#include<stdio.h>
#include<algorithm>
using namespace std;
int grundy[1<<16];
void init()
{
for(int i=0;i<(1<<16);i++)
grundy[i]=-1;
grundy[0]=0; //Zero element also P position
for(int i=0;i<16;i++)
grundy[1<<i]=0; //Single elements means P position
}
int isSorted(int arr[],int size,int position)
{
int l=-999; //As no element will be lesser than this
for(int i=size-1;i>=0;i--)
{
if(position & (1<<i))
{
if(arr[i]>l)
l=arr[i];
else
return 0;
}
}
return 1;
}
int solve(int arr[],int size,int position)
{
if(grundy[position]!=-1)
return grundy[position];
if(isSorted(arr,size,position))
{
grundy[position]=0; //Since already sorted, no moves are there
return 0;
}
int idx=0;
int count[size];
for(int i=0;i<size;i++) //We can remove any one element, so removing that, calculating and restoring the element
{
if(position & (1<<i))
{
position^=(1<<i); //Changes ith bit, got from stackoverflow
count[idx]=solve(arr,size,position); //Stores grundy number of a position to which we can go
idx++;
position^=(1<<i);
}
}
int ans=0;
sort(count,count+idx);
for(int i=0;i<idx;i++) //Finding grundy number of present position which minimum value to where we cannot move
{
if(ans==count[i])
{
while(ans==count[i])
i++;
i--; //decrementing coz it will be incremented again when loop ends
ans++;
}
}
grundy[position]=ans;
return ans;
}
int main()
{
int test,n;
scanf("%d",&test);
while(test--)
{
scanf("%d",&n);
int arr[n];
for(int i=0;i<n;i++)
scanf("%d",&arr[i]);
init();
if(solve(arr,n,(1<<n)-1)==0)
printf("Bob\n");
else
printf("Alice\n");
for(int i=0;i<(1<<n);i++)
printf("%d\t",grundy[i]);
}
}
Ly9GaW5kaW5nIFNwcmFndWUtR3J1bmR5IG51bWJlciBmb3IgZWFjaCBzdWJzZXQgb2YgdGhlIGFycmF5IGFuZCBmaW5kaW5nIHRoZSBhbnN3ZXIKI2luY2x1ZGU8c3RkaW8uaD4KI2luY2x1ZGU8YWxnb3JpdGhtPgp1c2luZyBuYW1lc3BhY2Ugc3RkOwppbnQgZ3J1bmR5WzE8PDE2XTsKdm9pZCBpbml0KCkKewoJZm9yKGludCBpPTA7aTwoMTw8MTYpO2krKykKCQlncnVuZHlbaV09LTE7CglncnVuZHlbMF09MDsJCQkvL1plcm8gZWxlbWVudCBhbHNvIFAgcG9zaXRpb24KCWZvcihpbnQgaT0wO2k8MTY7aSsrKQoJCWdydW5keVsxPDxpXT0wOwkJLy9TaW5nbGUgZWxlbWVudHMgbWVhbnMgUCBwb3NpdGlvbgp9CmludCBpc1NvcnRlZChpbnQgYXJyW10saW50IHNpemUsaW50IHBvc2l0aW9uKQp7CglpbnQgbD0tOTk5OwkJLy9BcyBubyBlbGVtZW50IHdpbGwgYmUgbGVzc2VyIHRoYW4gdGhpcwoJZm9yKGludCBpPXNpemUtMTtpPj0wO2ktLSkKCXsKCQlpZihwb3NpdGlvbiAmICgxPDxpKSkKCQl7CgkJCWlmKGFycltpXT5sKQoJCQkJbD1hcnJbaV07CgkJCWVsc2UKCQkJCXJldHVybiAwOwoJCX0KCX0KCXJldHVybiAxOwp9CmludCBzb2x2ZShpbnQgYXJyW10saW50IHNpemUsaW50IHBvc2l0aW9uKQp7CglpZihncnVuZHlbcG9zaXRpb25dIT0tMSkKCQlyZXR1cm4gZ3J1bmR5W3Bvc2l0aW9uXTsKCWlmKGlzU29ydGVkKGFycixzaXplLHBvc2l0aW9uKSkKCXsKCQlncnVuZHlbcG9zaXRpb25dPTA7CS8vU2luY2UgYWxyZWFkeSBzb3J0ZWQsIG5vIG1vdmVzIGFyZSB0aGVyZQoJCXJldHVybiAwOwoJfQoJCgkKCWludCBpZHg9MDsKCWludCBjb3VudFtzaXplXTsKCWZvcihpbnQgaT0wO2k8c2l6ZTtpKyspCQkvL1dlIGNhbiByZW1vdmUgYW55IG9uZSBlbGVtZW50LCBzbyByZW1vdmluZyB0aGF0LCBjYWxjdWxhdGluZyBhbmQgcmVzdG9yaW5nIHRoZSBlbGVtZW50Cgl7CgkJaWYocG9zaXRpb24gJiAoMTw8aSkpCgkJewoJCQlwb3NpdGlvbl49KDE8PGkpOwkvL0NoYW5nZXMgaXRoIGJpdCwgZ290IGZyb20gc3RhY2tvdmVyZmxvdwoJCQljb3VudFtpZHhdPXNvbHZlKGFycixzaXplLHBvc2l0aW9uKTsJLy9TdG9yZXMgZ3J1bmR5IG51bWJlciBvZiBhIHBvc2l0aW9uIHRvIHdoaWNoIHdlIGNhbiBnbwoJCQlpZHgrKzsKCQkJcG9zaXRpb25ePSgxPDxpKTsKCQl9Cgl9CglpbnQgYW5zPTA7Cglzb3J0KGNvdW50LGNvdW50K2lkeCk7Cglmb3IoaW50IGk9MDtpPGlkeDtpKyspCS8vRmluZGluZyBncnVuZHkgbnVtYmVyIG9mIHByZXNlbnQgcG9zaXRpb24gd2hpY2ggbWluaW11bSB2YWx1ZSB0byB3aGVyZSB3ZSBjYW5ub3QgbW92ZQoJewoJCWlmKGFucz09Y291bnRbaV0pCgkJewoJCQl3aGlsZShhbnM9PWNvdW50W2ldKQoJCQkJaSsrOwoJCQlpLS07CQkvL2RlY3JlbWVudGluZyBjb3ogaXQgd2lsbCBiZSBpbmNyZW1lbnRlZCBhZ2FpbiB3aGVuIGxvb3AgZW5kcwoJCQlhbnMrKzsKCQl9Cgl9CglncnVuZHlbcG9zaXRpb25dPWFuczsKCXJldHVybiBhbnM7CgkKfQppbnQgbWFpbigpCnsKCWludCB0ZXN0LG47CglzY2FuZigiJWQiLCZ0ZXN0KTsKCXdoaWxlKHRlc3QtLSkKCXsKCQlzY2FuZigiJWQiLCZuKTsKCQlpbnQgYXJyW25dOwoJCWZvcihpbnQgaT0wO2k8bjtpKyspCgkJCXNjYW5mKCIlZCIsJmFycltpXSk7CgkJaW5pdCgpOwoJCQoJCWlmKHNvbHZlKGFycixuLCgxPDxuKS0xKT09MCkKCQkJcHJpbnRmKCJCb2JcbiIpOwoJCWVsc2UKCQkJcHJpbnRmKCJBbGljZVxuIik7CgkJZm9yKGludCBpPTA7aTwoMTw8bik7aSsrKQoJCQlwcmludGYoIiVkXHQiLGdydW5keVtpXSk7Cgl9Cn0=