思路:由于是求区间的红气球个数,我们可以先求sum[i]表示i到n行的红球个数,利用递归思想求解
设置函数g(k,i) 表示第k小时,从i到n行的红气球个数,当i>2^k时,其实就为k-1时的情况相同,当i<=2^k时,即为k-1情况的两倍(上半部分)+下半部分的所有红气球
代码如下:
#include<cstdio>
#include<cstring>
int B[35];
long long tri[35];
long long g(int k,int i) //第k小时,第i行到第n行的红气球数
{
if(i<=0 || i>B[k])
return 0;
if(k<=0)
return 1;
if(i<=B[k-1])
return g(k-1,i)*2 + tri[k-1];
else
return g(k-1,i-B[k-1]);
}
int main()
{
int a,b,k,i,j;
tri[0]=1;
B[0]=1;
for(i=1;i<=30;i++)
{
tri[i]=tri[i-1]*3;
B[i]=B[i-1]<<1;
}
int T;
scanf("%d",&T);
for(int kase=1;kase<=T;kase++)
{
scanf("%d%d%d",&k,&a,&b);
printf("Case %d: ",kase);
printf("%lld\n",g(k,a)-g(k,b+1));
}
return 0;
}