[ABC283Ex] Popcount Sum
题面翻译
记 popcount ( n ) \text{popcount}(n) popcount(n) 为 n n n 的二进制表示中 1 1 1 的个数。
现在有 T T T 组询问,每组询问给定 n , m , r n, m, r n,m,r,请求出
∑ i m o d m = r n popcount ( i ) \sum_{i\bmod m = r}^n \text{popcount}(i) imodm=r∑npopcount(i)
即小于等于 n n n 且模 m m m 为 r r r 的正整数的 popcount \text{popcount} popcount 之和。
1 ≤ T ≤ 1 0 5 , 1 ≤ m ≤ n ≤ 1 0 9 , 0 ≤ r < m 1\le T \le 10^5,\ 1\le m \le n \le 10^9,\ 0\le r < m 1≤T≤105, 1≤m≤n≤109, 0≤r<m。
题目描述
以上 以下の整数であって、 で割った余りが になるものすべてに対する popcount の総和を求めてください。
ただし、正整数 に対して の popcount とは を二進表記したときの の個数、すなわち の位が となる非負整数 の個数のことです。
つの入力につき、 個のテストケースに答えてください。
输入格式
入力は以下の形式で標準入力から与えられる。入力の 行目は以下の通りである。
そして、 個のテストケースが続く。これらはそれぞれ以下の形式で与えられる。
输出格式
行出力せよ。 行目には 番目のテストケースに対する答えを出力せよ。
样例 #1
样例输入 #1
2
12 5 1
6 1 0
样例输出 #1
6
9
提示
制約
- 入力はすべて整数
Sample Explanation 1
つ目のテストケースでは、 の popcount が の popcount が の popcount が であるため の計算結果である を出力します。 つ目のテストケースでは、 の popcount が の popcount が の popcount が の popcount が の popcount が の popcount が であるため の計算結果である を出力します。
cpp
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll mian(ll a,ll b,ll c,ll n)
{
if (n<0) return 0;
if (!a||!n) return b/c*(n+1);
if (a>=c||b>=c) return n*(n+1)*(a/c)/2+(n+1)*(b/c)+mian(a%c,b%c,c,n);
return(a*n+b)/c*n-mian(c,c-b-1,a,(a*n+b)/c-1);
}
int t;ll n,m,r;
int main()
{
cin>>t;
while(t--)
{
scanf("%lld%lld%lld",&n,&m,&r);
ll ans=0;
for(ll i=1;i<=n;i<<=1) ans+=mian(m,r+i,i*2,(n-r)/m)-mian(m,r,i*2,(n-r)/m);
printf("%lld\n",ans);
}
return 0;
}