「学习笔记」快速幂

快速幂

时间复杂度

极大地加快了计算某数的某次幂的速度,能把朴素的 O ( n ) O(n) O(n) 优化为 O ( log ⁡ 2 n ) O(\log_2n) O(log2n)

原理

x y x^y xy,把 y y y 转成二进制,取每一位来进行运算
例如需求 6 3 6^3 63,则把 3 3 3 转为二进制,也就是 0011 0011 0011,取数出来的话就可得 2 0 × 1 + 2 1 × 1. 2^0 \times 1 + 2^1 \times 1. 20×1+21×1.
∴ ∴ 6 3 = 6 ( 2 0 × 1 ) × 6 ( 2 1 × 1 ) . 6^3=6^{(2^0 \times 1)} \times 6^{(2^1 \times 1)}. 63=6(20×1)×6(21×1).
以上。

程序实现

pascal model

function quick_power(x,y:longint):longint;
Var res,temp,i:longint;
Begin
        res:=1;
        temp:=x;
        i:=y;
        while i>0 do
        Begin
                if (i and 1>0) then
                Begin
                        res:=res*temp;
                end;
                temp:=sqr(temp);
                i:=i>>1;
        end;

        exit(res);
end;

c++ model

long long quick_power(long long x,long long y) {
	long long res=1,temp=x;
	for (register long long i=y;i;temp*=temp,i>>=1) {
		if (i&1) {
			res*=temp;
		}
	}
	
	return res;
}

例题

有道难题

Description
  从前有个人,叫好人。他非常擅长解决数学问题。今天他正在做这样的一道数学题:
  给定三个正整数X, Y和Z(X < Y, Z > 1)满足
    X ^ Z + Y ^ Z + X * Y * Z = K
  其中K是另一个给定的正整数,“\*”是乘法,“\^”表示乘幂运算,如2^3表示2的3次方,即2\*2\*2。
  找出该问题的一个解方案对好人来说是非常简单的事。现在,他想继续挑战一下:该等式总共有多少组不同的解方案呢?
  意外的是,这个好人居然做不出来。看来,这是一道难题。现在,是你的show time了。

Input
  输入包含多组数据。
  对于每组数据,只有一个整数K。
  当K = 0时表示输入结束。

Output
  对每组数据,输出一行,仅包含一个整数,表示解方案的个数。

Sample Input
9
53
6
0

Sample Output
1
1
0

100 p t s   c o d e : 100pts\ code: 100pts code:

#include <bits/stdc++.h>
typedef long long ll;
using  namespace std;

ll pow(ll x,ll y) {
	ll res=1,temp=x;
	for (register ll i=y;i;temp*=temp,i>>=1) {
		if (i&1) {
			res*=temp;
		}
	}
	
	return res;
}

ll check(ll x,ll y) {
	ll res=1;
	for(;pow(res,y)<=x;res++);
	
	return res-1;
}

int main() {
	ll k;
	scanf("%lld",&k);
	while (k) {
		ll tot=0;
		for (register ll z=2;z<31;z++) {
			ll y=check(k,z);
			for (register ll x=1;x<y;x++) {
				for (;x<y and pow(x,z)+pow(y,z)+x*y*z>k;y--);
				if (x<y and pow(x,z)+pow(y,z)+x*y*z==k) {
					tot++;
				}
			}
		}
		
		printf("%lld\n",tot);
		
		scanf("%lld",&k);
	}
	
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值