知识考量码【蓝桥】

这里 

  • 最大值不一定为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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值