输入描述:
每组测试数据包括一行,x(0<x<2000000000), y(0<y<2000000000), k(2<=k<=16)
输出描述:
输入可能有多组数据,对于每一组数据,root(x^y, k)的值
这道题同样也是一道数学题,硬算难度极大。查看网上别人的解法,大致有两种数学规律可以用于解答这道题。
第一种方法
x=a0+a1∗k+a2∗k2+...+an∗knx=a_0+a_1*k+a_2*k^2+...+a_{n}*k^{n}x=a0+a1∗k+a2∗k2+...+an∗kn
coefficient(x2)=∑i=1nai2+2∗∑i!=jnaia=(∑i=1nai)2coefficient(x^2)=\sum_{i=1}^{n}a_i^2+2*\sum_{i!=j}^{n}a_ia=(\sum_{i=1}^{n}a_i)^2coefficient(x2)=i=1∑nai2+2∗i!=j∑naia=(i=1∑nai)2
coefficient(x2)=(coefficient(x))2coefficient(x^2)=(coefficient(x))^2coefficient(x2)=(coefficient(x))2
因此可以递归化简此式。
root(x,y,k)=root((root(x,y/2,k))2,1,k),(y%2=0))root(x, y, k) = root((root(x, y / 2, k))^2, 1, k), (y\%2=0))root(x,y,k)=root((root(x,y/2,k))2,1,k),(y%2=0))
root(x,y,k)=root((root(x,y/2,k))2∗root(x,1,k),1,k),(y>1,y%2=1)root(x, y, k) = root((root(x, y / 2, k))^2 * root(x, 1, k), 1, k), (y>1,y\%2=1)root(x,y,k)=root((root(x,y/2,k))2∗root(x,1,k),1,k),(y>1,y%2=1)
root(x,1,k)=coefficient(x)root(x, 1, k) = coefficient(x)root(x,1,k)=coefficient(x)
AC代码
#include<iostream>
#include<cmath>
using namespace std;
int get(int x,int k){
while(x>=k){
int sum=0;
while(x!=0){
sum+=x%k;
x=x/k;
}
x=sum;
}
return x;
}
int root(int x,int y,int k){
if(y==1) return get(x,k);
else if(y%2==0) return get(pow(root(x,y/2,k),2),k);
else return get(pow(root(x,y/2,k),2)*root(x,1,k),k);
}
int main(){
int x,y,k;
while(cin>>x>>y>>k){
cout<<root(x,y,k)<<" ";
}
return 0;
}
第二种方法
第二种方法比第一种方法更加简单,但要用到快速模幂的方法。
N=a0+a1∗k+a2∗k2+...+an∗kn(N=xy)N=a_0+a_1*k+a_2*k^2+...+a_{n}*k^{n} (N=x^y)N=a0+a1∗k+a2∗k2+...+an∗kn(N=xy)
coefficient(N)=a0+a+a+...+acoefficient(N)=a_0+a+a+...+acoefficient(N)=a0+a+a+...+a
N−coefficient(N)=a1∗(k−1)+a2∗(k2−1)+...+an∗(kn−1)N-coefficient(N)=a_1*(k-1)+a_2*(k^2-1)+...+a_{n}*(k^{n}-1)N−coefficient(N)=a1∗(k−1)+a2∗(k2−1)+...+an∗(kn−1)
coefficient(N)−coefficient(coefficient(N))=a1′∗(k−1)+a2′∗(k2−1)+...+an′∗(kn−1)coefficient(N)-coefficient(coefficient(N))=a_1'*(k-1)+a_2'*(k^2-1)+...+a_{n}'*(k^{n}-1)coefficient(N)−coefficient(coefficient(N))=a1′∗(k−1)+a2′∗(k2−1)+...+an′∗(kn−1)
..........................................................................................递推可得:
(N−final(N))%(k−1)=0(N-final(N))\%(k-1)=0(N−final(N))%(k−1)=0
N%(k−1)=final%(k−1)N\%(k-1)=final\%(k-1)N%(k−1)=final%(k−1)
因此只需求N对k-1的余数就够了。
#include <stdio.h>
int main(){
for(long x,y,k,r;~scanf("%ld%ld%ld",&x,&y,&k);){
for(r=1,k-=1;y;r=(y&1?r*x%k:r),x=x*x%k,y>>=1);
printf("%ld\n",r?r:k);
}
return 0;
}