UVA 12627 Erratic Expansion

题意:求题目所示的图中,第k秒 第a,b行之间的红气球数目

首先 [a,b]之间 可转化为求[1,b]-[1,a] 这样更容易进行计算

其次 原题中的1编号不合理 所以我们可以把最下面一行  即原来的第1>>k 行 设成编号1

现在我们要求 从下到上的 前n行 的红气球数目(设为f(n) ),由于题目中构造方法 图案A的右面放上一块纯蓝的(无视掉就可以了) 上面放两块A

这样就有  f(16)=f(8)+2*f(8) f (8)=3*f(4)这样 而f(7)呢 从图中不难看出(或者自己推理出) f(7)=f(4)+2*f(3)

所以对于当前查询的n需要找到比他小的里最大的2的整数幂的数 ,可以预选把这些整数幂的值 连同其F值处理出来 这样复杂度就是 O(k)了 

(我是用一个map通过记忆化搜索来缩减时间,因为2的整数次幂的数会被频繁调用 所以时间差不多)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cctype>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<algorithm>
#include<set>
#define scnaf scanf
#define cahr char
#define bug puts("bugbugbug");
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int mod=1000000007;
const int maxn=5000+10;
const int inf=1e9;
int f[50];
map<int,ll>mp;
ll dfs(int x)
{
    if(x==1)return 1;
    if(x==0)return 0;
    if(mp[x]) return mp[x];
    int id=lower_bound(f,f+32,x)-f;
    id=f[id-1];
    return mp[x]=dfs(id)+2*dfs(x-id);

}
int main()
{
    for(int i=0;i<=31;i++) f[i]=1<<i;
    int T_T,k,a,b,test=1;
    scanf("%d",&T_T);
    while(T_T--)
    {
        scanf("%d%d%d",&k,&a,&b);
        int n=1<<k;
        a=n-a+1; b=n-b+1;
        if(a>b)swap(a,b);
        printf("Case %d: %lld\n",test++,dfs(b)-dfs(a-1));
    }
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值