Setsuna的K数列 进制转换 快速幂
题目描述
Komorebi非常喜欢数列,但他实在太弱了无法想象出一个数列该如何构造,于是他就去FD(Frog Department)找Setsuna求助,Setsuna是一名光荣的FTCer(Frog,Time Controller),并没有很多空闲,就随口给Komorebi构造了一个神秘的KK数列,构建方法如下:
1、创建一个集合A_KA
K
,集合内包含KK的所有整数次幂,如当K=3K=3时,A_3A
3
包含1,3,9,27\dots1,3,9,27…,但不会包含2,4\dots2,4…。
2、取A_KA
K
内任意个元素各一个相加,并将他们放进一个新的集合B_KB
K
。
3、将B_KB
K
内的元素从小到大排序,得到的有序数列即是一个KK数列S_KS
K
。
例如当K=3K=3时,S_3={1,3,4(3+1),9,10(9+1),12(9+3),13(9+3+1),\dots}S
3
={1,3,4(3+1),9,10(9+1),12(9+3),13(9+3+1),…}。
Komorebi拿到这个数列后很开心,每天都要盯着这个KK数列看很久。久而久之这个数列有些数被Komorebi弄丢了,Komorebi想复原这个数列,又不好意思再去找Setsuna,他就只能来求助你了。
Komorebi想知道KK数列S_KS
K
的第nn项是多少,你可以帮帮他吗?当然这个数有可能会非常大,因此请输出答案对10^9+710
9
+7取模后的结果。
输入描述:
仅一行包含两个整数nn和KK。
输出描述:
一个整数,表示答案对10^9+710
9
+7取模后的结果。
示例1
输入
复制
5 3
输出
复制
10
一开始以为是什么数学题,直接跳了,其实是进制相关,k的每个次幂要么使用,要么不使用,对应0和1,即二进制,而且由于位权递增,从小到大第n个的组合数即是n对应的二进制对应的那种情况。所以这题就是将n转换为二进制,把对应为1的位权加起来,过程中取模,需要用到快速幂
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n,k,ans,p,mod=1e9+7;
ll pow_mod(ll a,ll n,ll m)
{
if(n==0)return 1;
ll x=pow_mod(a,n/2,m);
ll ans=x*x%m;
if(n%2==1)ans=ans*a%m;
return ans;
}
int main(){
cin>>n>>k;
while(n){
ll t=n%2;
n/=2;
if(t==1){
ans+=pow_mod(k,p,mod);
ans%=mod;
}
p++;
}
cout<<ans;
return 0;
}