【题目描述】:
淘淘家有棵奇怪的苹果树,这棵树共有n+1层,标号为0~n。这棵树第0层只有一个节点,为根节点。已知这棵树为b叉树,且保证是一颗满b叉树。
现在,该树第n层的每个节点上都结出了一个苹果,淘淘想知道共结了多少苹果。由于数量可能很大,答案要求输出mod k后的结果。
【输入描述】:
给出第1层的节点数b和层数n和k
【输出描述】:
输出苹果数mod k后的结果。
【样例输入】:
2 10 9
【样例输出】:
7
【时间限制、数据范围及描述】:
时间:1s 空间:32M
30%的数据保证:b<=100,n<=10, k<=100.
100%的数据保证:b<2^31,n<2^31,k<=2^15.
本题说是一颗树,其实就是求b的n次幂模k的值。运用到了快速幂,就是不使用暴力算法,而采取分段计算的思想。
1.如果b是偶数,我们可以记k = a2 mod c,那么求(k)b/2 mod c就可以了。
2.如果b是奇数,我们也可以记k = a2 mod c,那么求((k)b/2 mod c × a ) mod c =((k)b/2 mod c * a) mod c 就可以了
以下是代码:
#include<stdio.h>
#include<iostream>
using namespace std;
long long ans;
long long read()//快速读入(好像没有必要)
{
char c;
long long ans=0,f=1;
c=getchar();
while(c<'0'||c>'9')
{
if(c=='-')
{
f=-1;
}
c=getchar();
}
while(c>='0'&&c<='9')
{
ans=ans*10+c-'0';
c=getchar();
}
return ans*f;
}
void work(long long b,long long n,long long k)//快速幂
{
ans=1;
while(n!=0)
{
if(n&1)
ans=ans*b%k;
b=b*b%k;
n=n/2;
}
return ;
}
int main()
{
long long b=0,n=0,k=0;
b=read();
n=read();
k=read();
work(b,n,k);
printf("%lld",ans);
return 0;
}
简化之后的模板,更加易懂的可以写成:
int PowerMod(int a, int b, int c)
{
int ans = 1;
a = a % c;
while(b > 0)
{
if(b % 2 = = 1)
ans = (ans * a) % c;
b = b / 2;
a = (a * a) % c;
}
return ans;
}