/*
http://acm.uestc.edu.cn/problem.php?pid=1711&cid=169
题意:岛上有n种宝藏,每一种宝藏有x个,它的价值为2^a。(x<10^9,a<10^5)
现在给出n种宝藏的个数x和价值a,要你将它分成两份是它们差值最小并输出差值。
思路:开始以为是背包问题,但是做不出来,正确的做法是:跟它的价值是2的次方有关系。
假如宝藏有x个,而x是个奇数,那么没办法我们只能把一边多分一个2^a(先保存好,等下再讨论分给谁)。
剩余的我们不分把她它弄成是(x/2)个价值为2^(a+1)的宝藏。(这里我们需要从a最小的开始)这样一直往上推,把宝藏弄成全部是bc[i][0]*2^i的形式,
而bc[i][1]记录是否由下面2^(i-1)生成的(其中bc[i][0]=1(或0),表示有(没有)2^i的这种宝藏,bc[i][1]=1(或0),表示由(不由)2^(i-1)构成)。
我现在又从高位往低位判断,
1、如果2^j不存在,继续往下分配。
2、如果存在则分两种情况讨论
(1)、这个宝藏是由2^(j-1)构成的,那么我们把这种宝藏分成2^(j-1),平均分配给两边。继续往下分配。
(2)、如果不是,我们把这个宝藏分配给一边,把比这个宝藏阶层小的分配给另一边。分配结束。
差值为2^(j)-bc[j-1][0]*2^(j-1)-bc[j-2][0]*2^(j-2)-……-bc[0][0]*2^0;
输出其对应的2进制即可。
*/
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
struct node{
long long a,x;
}ac[1100000];
long long bc[1100000][2];
bool cmp(node aa,node bb)
{ return aa.a<bb.a;}
int main()
{
long long t,n,c,cnt=1;
long long i,j;
scanf("%lld",&t);
while(t--)
{
scanf("%lld",&n);
for(i=0;i<n;i++)
scanf("%lld %lld",&ac[i].a,&ac[i].x);
sort(ac,ac+n,cmp);
memset(bc,0,sizeof(bc));
int len=0;
for(i=1;i<n;i++)
if(ac[len].a==ac[i].a) ac[len].x+=ac[i].x;
else
{
len++;
ac[len].a=ac[i].a;
ac[len].x=ac[i].x;
}
c=0;j=0;
for(i=0;i<=ac[len].a;i++)
{
if(j<n&&i==ac[j].a){
if(c>0) bc[i][1]=1;
c+=ac[j].x;
j++;
bc[i][0]=c%2;
c/=2;
}
else
{
bc[i][0]=c%2;
bc[i][1]=1;
c/=2;
}
}
for(i=ac[len].a;i>0;i--)
if(bc[i][0]==0||(bc[i][0]==1&&bc[i][1]==1)) bc[i][0]=0;
else
break;
printf("Case #%lld: ",cnt++);
if(i==0) printf("%lld\n",bc[0][0]);
else
{
c=0;
for(j=0;j<=i;j++)
{
if(c==0)
{
bc[j][0]^=c;
c=bc[j][0];
}
else
bc[j][0]^=c;
}
while(bc[i][0]==0) i--;
for(j=i;j>=0;j--)
printf("%lld",bc[j][0]);
printf("\n");
}
}
return 0;
}