知识考量码【蓝桥】
这里
- 最大值不一定为k
- 每个1可以选择在n种的任意一个时刻由0变1
- 含有x个1的数有多个
//
// Created by yumo_
//
#include<bits/stdc++.h>
using namespace std;
#define scin std::cin
#define scout std::cout
using i64=long long;
const int INF=INT_MAX/2;
const i64 INFF=LLONG_MAX/2;
const i64 md=1e9+7;
const int M=1e5+7;
struct xxx {
i64 a,b,c;
bool operator<(const xxx &other) const {
if (other.c==c)return other.a<a;
else return other.c<c;//由大到小
}
};
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int T;
// scin>>T;
T=1;
for (;T>0;--T) {
auto pow=[&](i64 a,i64 b,i64 Md) {
i64 res=1;
while (b>0) {
if (b&1) res=res*a%Md;
a=a*a%Md;
b>>=1;
}
return res;
};
i64 n,k;scin>>n>>k;
//最大值不一定为k
//每个1可以选择在n种的任意一个时刻由0变1
//含有x个1的数有多个
std::vector<std::vector<i64>> Cal(32,std::vector<i64>(32,0));
auto Comb=[&](auto self,i64 n,i64 m) {
if (m==0||m==n)return 1ll;
if (Cal[n][m]!=0)return Cal[n][m];
return Cal[n][m]=(self(self,n-1,m)+self(self,n-1,m-1))%md;
};
int len=0;
std::vector<i64> cnt(32,0);
for (int i=30;i>=0;--i) {//倒着可以两头堵
if ((k>>i)&1) {
//前i+1保持不变
for (int j=0;j<=i;++j) {//二进制i位实际上是i+1个位置,100->011
cnt[len+j]=(cnt[len+j]+Comb(Comb,i,j))%md;
}
len++;
}
}
cnt[len]=(cnt[len]+1)%md;//单独k
i64 ans=1;//0
for (int i=1;i<31;++i) {
ans=(ans+cnt[i]*pow(n,i,md)%md)%md;
}
scout<<ans<<"\n";
}
// auto pow=[&](i64 a,i64 b,i64 Md) {
// i64 res=1;
// while (b>0) {
// if (b&1) res=res*a%Md;
// a=a*a%Md;
// b>>=1;
// }
// return res;
// };
// 18 22 24
return 0;
}