题意:
题解:
对于第i位的贡献就是
∑
k
=
1
n
k
∗
M
2
i
−
2
∗
k
∗
m
2
i
+
1
\sum^{n}_{k=1}\frac{k*M}{2^i}-2*\frac{k*m}{2^{i+1}}
∑k=1n2ik∗M−2∗2i+1k∗m
这个式子表示的是在k*M的时候,第i位是1还是0
那么我们只需要算它的前缀和再乘上
2
i
2^i
2i即可,解决这种问题使用的是类欧几里得算法:
注意会爆long long
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll mod=1e9+7;
ll f(__int128 a,__int128 b,__int128 c,__int128 n)
{
ll m=(a*n+b)/c;
if(!a || !m)return 0;
if(a>=c || b>=c)return (n*(n+1)/2%mod*(a/c)%mod+(b/c)*(n+1)%mod+f(a%c,b%c,c,n))%mod;
return (n*m%mod+mod-f(c,c-b-1,a,m-1)%mod)%mod;
}
int main()
{
ll n,m,ans=0;
scanf("%lld%lld",&n,&m);
for(ll ret=1,i=0;i<=40;i++,ret*=2)
{
if((m>>i)&1)
ans=(ans+(ret%mod*(f(m,0,ret,n)-2*f(m,0,ret*2,n)))%mod+mod)%mod;
}
printf("%lld\n",ans);
return 0;
}