[ABC283Ex] Popcount Sum

我的社区http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=3svdDJTlkD76TRRShbxYCYK1zK1c8cyF&authKey=v1pxp6rS8AA4SRy7bflJl9LIwp8d5v0HOudw%2BDxHiWDRqZ1LzjeoBJH1Z1EXnl35&noverify=0&group_code=546881376

[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。

题目描述

$ 1 $ 以上 $ N $ 以下の整数であって、$ M $ で割った余りが $ R $ になるものすべてに対する popcount の総和を求めてください。

ただし、正整数 $ X $ に対して $ X $ の popcount とは $ X $ を二進表記したときの $ 1 $ の個数、すなわち $ 2^k $ の位が $ 1 $ となる非負整数 $ k $ の個数のことです。

$ 1 $ つの入力につき、 $ T $ 個のテストケースに答えてください。

输入格式

入力は以下の形式で標準入力から与えられる。入力の $ 1 $ 行目は以下の通りである。

$ T $

そして、$ T $ 個のテストケースが続く。これらはそれぞれ以下の形式で与えられる。

$ N $ $ M $ $ R $

输出格式

$ T $ 行出力せよ。$ i $ 行目には $ i $ 番目のテストケースに対する答えを出力せよ。

样例 #1

样例输入 #1

2
12 5 1
6 1 0

样例输出 #1

6
9

提示

制約

  • $ 1\ \leq\ T\ \leq\ 10^5 $
  • $ 1\ \leq\ M\ \leq\ N\ \leq\ 10^9 $
  • $ 0\ \leq\ R\ <\ M $
  • 入力はすべて整数

Sample Explanation 1

$ 1 $ つ目のテストケースでは、$ 1 $ の popcount が $ 1 、 、 、 6 $ の popcount が $ 2 、 、 、 11 $ の popcount が $ 3 $ であるため $ 1+2+3 $ の計算結果である $ 6 $ を出力します。 $ 2 $ つ目のテストケースでは、$ 1 $ の popcount が $ 1 、 、 、 2 $ の popcount が $ 1 、 、 、 3 $ の popcount が $ 2 、 、 、 4 $ の popcount が $ 1 、 、 、 5 $ の popcount が $ 2 、 、 、 6 $ の popcount が $ 2 $ であるため $ 1+1+2+1+2+2 $ の計算結果である $ 9 $ を出力します。

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;
}
相关推荐
顶呱呱程序5 分钟前
2-143 基于matlab-GUI的脉冲响应不变法实现音频滤波功能
算法·matlab·音视频·matlab-gui·音频滤波·脉冲响应不变法
&岁月不待人&12 分钟前
Kotlin by lazy和lateinit的使用及区别
android·开发语言·kotlin
StayInLove15 分钟前
G1垃圾回收器日志详解
java·开发语言
TeYiToKu17 分钟前
笔记整理—linux驱动开发部分(9)framebuffer驱动框架
linux·c语言·arm开发·驱动开发·笔记·嵌入式硬件·arm
无尽的大道23 分钟前
Java字符串深度解析:String的实现、常量池与性能优化
java·开发语言·性能优化
互联网打工人no124 分钟前
每日一题——第一百二十四题
c语言
爱吃生蚝的于勒27 分钟前
深入学习指针(5)!!!!!!!!!!!!!!!
c语言·开发语言·数据结构·学习·计算机网络·算法
羊小猪~~30 分钟前
数据结构C语言描述2(图文结合)--有头单链表,无头单链表(两种方法),链表反转、有序链表构建、排序等操作,考研可看
c语言·数据结构·c++·考研·算法·链表·visual studio
binishuaio36 分钟前
Java 第11天 (git版本控制器基础用法)
java·开发语言·git
zz.YE38 分钟前
【Java SE】StringBuffer
java·开发语言