UVA 12627 气球胀啊胀

题目在此

题意:第0个小时有一个红气球,每过一个小时,一个红气球膨胀为3个红球和1个蓝球
一个蓝球膨胀为4个蓝球,排成下图的样子,问过了k小时,第a行到第b行有多少个红球

看下题目里的图,把每个图十字分开,就很容易发现k和k+1的关系
除了右下角全是蓝色以外,剩下都是复制

这里写图片描述
f[k][i] 表示第k个小时,前i行有多少个红球
当i在上半区(1到(1<<(k-1))行)的时候,气球是复制的k-1的状态,只需 *2即可
。。。下。。。。。。,把上半区的全加上,再加上k-1时前(i-上半区行数)行的气球
c[k]=第k个小时红色气球总数

这里写图片描述

答案输出f[k][b]-f[k][a-1]即可

这里写图片描述

#include<cstdio>
#include<iostream>
#include<algorithm>
typedef long long LL;
using namespace std;
const int N=40000;
int i,k,a,b;
LL c[40];

LL f(int k,int i){
    if (i<=0)return 0;
    if (k==0)return 1;
    if (i<=(1<<(k-1)))return f(k-1,i)<<1;
    return c[k-1]*2+f(k-1,i-(1<<(k-1)));
}

int main(){
    //freopen("fuck.in","r",stdin);
    int T;scanf("%d",&T);
    c[0]=1;for (int i=1;i<=31;i++)c[i]=c[i-1]*3;
    for (int cas=1;cas<=T;cas++){
        scanf("%d%d%d",&k,&a,&b);
        printf("Case %d: %lld\n",cas,f(k,b)-f(k,a-1));
    }
    return 0;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值