【EOJ Monthly 2019.02 - D】进制转换(思维,取模,高精度大数)

版权声明:欢迎学习我的博客,希望ACM的发展越来越好~ https://blog.csdn.net/qq_41289920/article/details/87934333

题干:

单测试点时限: 2.0 秒

内存限制: 256 MB

“他觉得一个人奋斗更轻松自在。跟没有干劲的人在一起厮混,只会徒增压力。”

QQ 小方决定一个人研究研究进制转换。

很快,QQ 小方就遇到问题了。他现在想知道在十进制范围 [l,r] 内有多少整数满足在 k 进制下末尾恰好有 m 个 0 。

比如在十进制下的 24 在二进制下是 11000 ,我们称十进制下的 24 在二进制下末尾恰好有 3 个 0 。

QQ 小方一筹莫展,你能帮他解决问题吗?

输入

第一行包含一个整数 T (1≤T≤105 ) 表示数据组数。

对于每组数据包含一行,四个整数 l,r,k,m ( 1≤l≤r≤1018 , 2≤k,m≤100 ),含义如题目所述。

输出

对于每组数据输出一行,包含一个整数,表示答案。

样例

Input

2
1 10 2 3
1 100 2 3

Output

1
6

提示

例如,在 100 进制下,末位是 90 的数不算作有末尾 0 。

解题报告:

然后作差就行了。

但是注意这题要处理高精度问题。处理方法有两个,要么变乘法为除法,要么换范围更大的整数(选稍微比longlong大一点的就可以了)

AC代码1:

#include<cstdio>
#include<assert.h>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define ll long long
#define fi first
#define se second
#define pb push_back
#define pm make_pair
using namespace std;
const int MAX = 2e2 + 6;
const ll INF = 0x3f3f;
ll l,r,k,m;
unsigned ll tmp;
unsigned ll cal(unsigned ll x) {
	unsigned ll res = 0;
	res = x / tmp;
	if(tmp * k <= x && tmp*k >= 0) res -= x/(tmp*k) ;
	return res;
}
int main()
{
	int t,n;
	cin>>t;
	while(t--) {
		scanf("%lld%lld%lld%lld",&l,&r,&k,&m);
		tmp = 1;
		int flag = 1;
		for(int i = 1; i<=m; i++) {
			tmp *= k;
			if(tmp > r || tmp < 0) {
				flag = 0; break;
			}
		}
		if(!flag) {
			printf("0\n");continue;
		}
		printf("%lld\n",cal(r) - cal(l-1));
	} 
	return 0 ;
 } 

AC代码2:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
int get(ll x,int k)
{
	int res=0;
	while(x)
	{
		res++;
		x/=k;
	}
	return res;
}
int main()
{
	int T,k,m;
	scanf("%d",&T);
	while(T--)
	{
		ll l,r;
		scanf("%lld%lld%d%d",&l,&r,&k,&m);
		int tmp=get(r,k);
		if(tmp<=m)
		{
			puts("0");
			continue;
		}
		ll x=pow(1ll*k,m);
		ll ans=r/x-(l-1)/x;
		if(r/x>=k)ans-=(r/(x*k)-(l-1)/(x*k));
		printf("%lld\n",ans);
	}
}

或者使用Python:

T=int(input())
for i in range(T):
    l,r,k,m=map(int,input().split())
    now=k**m
    a=now*k
    print((r//now-(l-1)//now)-(r//a-(l-1)//a))

猜你喜欢

转载自blog.csdn.net/qq_41289920/article/details/87934333