0


河南萌新联赛2024第(三)场:F累加器(前缀和)

题目描述

存在一个累加器,每次可以对一个数进行加 111 操作,此时在二进制下有一些位发生改变,对一个数 xxx 进行 yyy 次累加操作,总共有多少位发生改变。

输入描述:

  1. 第一行一个正整数 TTT (1T105)(1\leq T \leq 10^5)(1T105)代表多组询问。
  2. 接下来 TTT 每行两个正整数 x,y(1x,y106)x,y(1\leq x,y \leq 10^6)x,y(1x,y106),代表对 xxx 进行 yyy 次累加操作。

输出描述:

  1. TTT 行每组询问一行代表总共发生改变的位数。

示例1

输入

复制4 1 4 10 1 20 20 1 100

  1. 4
  2. 1 4
  3. 10 1
  4. 20 20
  5. 1 100

输出

复制7 1 40 197

  1. 7
  2. 1
  3. 40
  4. 197

说明

  1. 对于第一个样例开始 (0001)2(0001)_2(0001)2 进行 444 次累加。
  2. 第一次 (0010)2(0010)_2(0010)2 两位改变。
  3. 第二次 (0011)2(0011)_2(0011)2 一位改变。
  4. 第三次 (0100)2(0100)_2(0100)2 三位改变。
  5. 第四次 (0101)2(0101)_2(0101)2 一位改变。

做法

先预处理前缀和,前缀和数组表示为从1到i的转换次数。

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. int t,ans;
  4. int x,y;
  5. int qzh[2000010];
  6. int main(){
  7. scanf("%d",&t);
  8. for(int i=1;i<=2000000;i++){
  9. int x=i^(i-1);//i和i-1二进制不同的话,该位是1
  10. int cnt=0;
  11. while(x){
  12. if(x&1) cnt++;//看有多少个1
  13. x >>= 1;
  14. }
  15. qzh[i]=qzh[i-1]+cnt;
  16. }
  17. while(t--){
  18. ans=0;
  19. scanf("%d%d",&x,&y);
  20. y+=x;
  21. cout<<qzh[y]-qzh[x]<<endl;
  22. }
  23. }

比赛时写超时了,我还真的去暴力模拟了。然后发现有类似1213121412131215的规律,想了半天想表示这个规律,太难,弄不出来。就一直在转牛角尖,也没想到用别的方法。

标签: 算法

本文转载自: https://blog.csdn.net/2301_80718054/article/details/140831166
版权归原作者 .jh_hj. 所有, 如有侵权,请联系我们删除。

“河南萌新联赛2024第(三)场:F累加器(前缀和)”的评论:

还没有评论