【NOIP模拟】Number

                                            Number

题目描述

如果一个数能够表示成两两不同的 3 的幂次的和,就说这个数是好的。
比如 13 是好的,因为 13 = 9 + 3 + 1 。
又比如 90 是好的,因为 90 = 81 + 9 。
现在我们用 a[i] 表示第 i 小的好数。
比如 a[1] = 1, a[2] = 3, a[5] = 10 。
给定 L,R,请求出 a[L] 到 a[R] 的 和 mod 232。

输入格式

第一行一个整数 T,表示数据组数。
接下来 T 行,每行两个整数 L,R 表示一组询问。

输出格式

输出 T 行,每行为一个整数,表示相应询问的答案。

样例数据 1

输入


1 3 
3 3 
4 5 
6 7 
2 5

输出



19 
25 
26

备注

【数据范围】
对 30% 的输入数据:1≤T≤100;R≤1000 。
对 100% 的输入数据:1≤T≤100000;1≤L≤R≤1018 。

 

解析:

       首先我们可以发现将 a[i] 转化成二进制再转成三进制就是第 i 小的数,于是我们可以用类似数位DP的的方法完成,详情见代码。

 

代码:

#include <bits/stdc++.h>
#define int unsigned long long
using namespace std;

const int Max=61;
const int mod=4294967296;
int l,r,t;
int Pow[Max],sum[Max];

inline int get_int()
{
	int x=0,f=1;
	char c;
	for(c=getchar();(!isdigit(c))&&(c!='-');c=getchar());
	if(c=='-'){f=-1;c=getchar();}
	for(;isdigit(c);c=getchar()) x=(x<<3)+(x<<1)+c-'0';
	return x*f;
}

inline void pre()
{
	Pow[0]=sum[0]=1;
	for(int i=1;i<=60;i++) Pow[i]=Pow[i-1]*3,sum[i]=sum[i-1]+Pow[i];
}

inline int solve(int num)
{
	int ans=0,now=0;
	for(int i=60;i>=1;i--)
	  if((1LL<<i)&num)
	  {
	  	ans+=sum[i-1] * (1LL<<(i-1));  //计算每一位数出现的次数之和乘以前缀和
	  	ans+=now * (1LL<<i);
	  	ans+=Pow[i],now+=Pow[i];
	  }
	if(num&1) ans+=now+1;    //最后一位需要特判
	return ans;
}

signed main()
{
	pre();
	t=get_int();
	while(t--)
	{
	  l=get_int(),r=get_int();
	  cout<<(solve(r)-solve(l-1))%mod<<"\n";
	}

	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
NOI(全国青少年信息学奥林匹克竞赛)模拟赛的测试据是指用于评测参赛选手的程序的输入和对应的输出。测试据是非常重要的,因为它决定了参赛选手的程序能否正确地解决问题。 在NOI模拟赛中,测试据具有以下特点: 1.充分覆盖:测试据应涵盖各种可能的输入情况,包括边界条件和极端情况。通过提供不同的测试据,可以考察选手对问题的全面理解和解决能力。 2.随机性和均衡性:为了公平起见,测试据应该是随机生成的,而不是针对某个特定算法或解法设计的。同时,测试据应该是均衡的,即各种情况的概率应该大致相等,以避免偏向某些解法。 3.合理性和可行性:测试据应该是合理和可行的,即符合题目要求的输入据,并且是选手能够通过编写程序来处理的。测试据应该考虑到程序的限制和时间复杂度,以充分测试选手的编程能力。 NOI模拟赛的测试据通常由经验丰富的考题组负责生成。他们会根据题目的要求和限制,设计出一组合理、充分、随机和均衡的测试据,以确保参赛选手的程序在各种情况下都能正确运行,并且能通过性能测试。 总之,测试据在NOI模拟赛中起到了至关重要的作用,它既考察了选手对问题的理解和解决能力,又提高了选手编程的技巧和效率。同时,合理和恰当的测试据也是公平竞赛的保证,确保每个参赛选手有相同的机会和条件进行竞争。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值