15行代码AC——Link/Cut Tree CodeForces - 614A(爆long long处理+快速幂讲解)

励志用少的代码做高效表达


Problem describe

Programmer Rostislav got seriously interested in the Link/Cut Tree data structure, which is based on Splay trees. Specifically, he is now studying the expose procedure.
Unfortunately, Rostislav is unable to understand the definition of this procedure, so he decided to ask programmer Serezha to help him. Serezha agreed to help if Rostislav solves a simple task (and if he doesn’t, then why would he need Splay trees anyway?)
Given integers l, r and k, you need to print all powers of number k within range from l to r inclusive. However, Rostislav doesn’t want to spent time doing this, as he got interested in playing a network game called Agar with Gleb. Help him!

Input

The first line of the input contains three space-separated integers l, r and k (1 ≤ l ≤ r ≤ 1018, 2 ≤ k ≤ 109).

Output

Print all powers of number k, that lie within range from l to r in the increasing order. If there are no such numbers, print “-1” (without the quotes).


题意分析

题意:输入l,r,k,输出所有在[l,r]区间内的k的幂次。
如:输入1,10,2 输出1 2 4 8

分析:求幂次不必多说,pow()累乘快速幂都可以。
但在求解过程中,会出现爆long long的情况, 如:k的n次幂=10^18, k=1000, 此时若继续计算,就会出现10^21 的数。超过了long long的取值范围,连unsigned long long都无法储存。

解决办法是:乘法变除法。

如:将式if(pow(k, i) <= r ) 改为:if(pow(k,i-1) <= r/k) 这样就可以在long long的范围内取值了。

下面列出两种AC代码, 代码一为快速幂求法, 代码二为朴素求法

如果对快速幂不甚了解,请移步——>快速幂基本思想讲解


代码一(快速幂求法)

#include<iostream>
#include<cmath>
using namespace std;
typedef long long ll;
ll quick_power(ll a, ll q) {
    
    
	ll sum = 1;
	while(q) {
    
    
		if(q%2==1) sum *= a;
		a*=a;
		q /= 2;
	}
	return sum;
}
int main( ) {
    
    
	ll l, r, k; cin>>l>>r>>k;
	bool flag = true;
	for(ll i = 0; quick_power(k, i)<=r ; i++) {
    
    
		ll num = quick_power(k,i);
		if(num>=l) {
    
    
			cout <<(flag?"":" ")<< num;
			flag = false;
		}
		if(num > r/k) break;
	}
	if(flag) cout << -1;
return 0; }

代码二(朴素求法)

#include<iostream>
#include<cmath>
using namespace std;
typedef unsigned long long llu;
int main( ) {
    
    
	llu l, r, k; cin>>l>>r>>k;
	llu t = 1, flag=0;
	while(t <= r) {
    
    
		if(t>=l) {
    
     cout << t << ' '; flag = 1; }
		if(t>r/k) break;
		t*=k; 
	}
	if(!flag) cout << -1;
return 0; }

这世界就是,一些人总在昼夜不停的努力,而另外一些人,起床就发现世界已经变了。

猜你喜欢

转载自blog.csdn.net/weixin_43899069/article/details/108319179