题意:开始有1个红气球,每小时后1个红气球会变为3个红气球和1个蓝气球,问k小时后第A行到第B行的气球数。
解:用g(k,i)表示第k小时时,从底部数i行的红气球数。所以ans = g(k,2^k-A+1) - g(k,2^k -B)
k小时情况由4个k-1小时时的情况组成由k1,k2,k3,k4表示
如果i所求的区域包含k1,k2,由于k4部分全部是蓝气球,所以求得是2*(k1中在区域中的) + k3
即 i >= 2^(k-1),则 g(k,i) = 2 * g(k-1,i-2 ^ (k-1)) + c(i);其他则g(k,i) = g(k-1,i);
其中c(0) = 1,c(i) = 3*c(i-1);
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <stack>
#include <cctype>
#include <string>
#include <malloc.h>
#include <queue>
#include <map>
#include <set> using namespace std; const int INF = 0xffffff;
const double esp = 10e-;
const double Pi = * atan(1.0);
const int maxn = + ;
const long long mod = ;
const int dr[] = {,,-,,-,,-,};
const int dc[] = {,,,-,,-,-,};
typedef long long LL; LL gac(LL a,LL b){
return b?gac(b,a%b):a;
} long long g(int k,int i){
if(k == ){
if(i >= )
return ;
else
return ;
}
if(i >= << (k-)){
long long c = pow(,k-)+esp;
return * g(k-,i- (<< (k-))) + c;
}
else{
return g(k-,i);
}
} int main()
{
#ifndef ONLINE_JUDGE
freopen("inpt.txt","r",stdin);
// freopen("output.txt","w",stdout);
#endif
int t;
scanf("%d",&t);
for(int cas = ;cas <= t;cas++){
int A,B,k;
scanf("%d%d%d",&k,&A,&B);
long long tmp = << k;
long long a = g(k,tmp-A+);
long long b = g(k,tmp-B);
printf("Case %d: %lld\n",cas,a-b);
}
return ;
}