从贡献角度考虑。遍历 k 的每一位,若这一位为 0,计算有多少个 ij 这一位为1。反之计算这一位有多少个数字为 0。
计算有多少个 ij 第 p 位为 1,等价于计算 我们固定i, 会发现这个是类欧几里得算法形式,套个类欧的模板即可。原博主
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int mod=1e9+7;
const int inv2=500000004;
ll f(ll a, ll b, ll c, ll n) {
if(a == 0)
return (n+1) * (b/c)%mod;
if(a < c && b < c) {
ll m = (a*n+b)/c;
if(m == 0)
return 0;
return (n*(m%mod)%mod - f(c, c-b-1, a, m-1)+mod)%mod;
}
return (f(a%c, b%c, c, n) + (n+1)*(b/c)%mod + (n+1)*n%mod*inv2%mod*(a/c)%mod)%mod;
}
int main()
{
ll n,k;
cin>>n>>k;
ll ans=0;
for(int j=0;j<=35;j++)
{
int flag=(k>>j)&1;
ll s=1ll<<j;
for(int i=0;i<=n;i++) //枚举i
{
ll x=f(i,0,s,n);
ll y=f(i,0,s+s,n)*2%mod;
x=((x-y)%mod+mod)%mod; //1的个数
if(flag)
{
ans=(ans+(n-x+1)*s%mod)%mod;
}
else
{
ans=(ans+x*s%mod)%mod;
}
}
}
cout<<(ans+mod)%mod<<endl;
return 0;
}