H:异或和之和

题目:
异或和之和
时间限制: 1.0s 内存限制: 256.0MB 本题总分:20 分
【问题描述】
给定一个数组 A i ,分别求其每个子段的异或和,并求出它们的和。或者说,对于每组满足 1 ≤ L ≤ R ≤ n 的 L,R ,求出数组中第 L 至第 R 个元素的异或和。然后输出每组 L,R 得到的结果加起来的值。
【输入格式】
输入的第一行包含一个整数 n 。第二行包含 n 个整数 A i ,相邻整数之间使用一个空格分隔。
【输出格式】
输出一行包含一个整数表示答案。
【样例输入】
5
1 2 3 4 5
【样例输出】
39
【评测用例规模与约定】
对于 30% 的评测用例,n ≤ 300 ;
对于 60% 的评测用例,n ≤ 5000 ;
对于所有评测用例,1 ≤ n ≤ 10^5 ,0 ≤ A i ≤ 2^20 。

这道题的暴力做法是枚举所有的字串 求异或和,再总求和

更好的解法,关于异或,更好的解法就是 弄清楚异或的本质
异或的本质其实是 对每一个数的二进制位进行异或,于是我们维护
一个二进制异或和的表,然后从前到后依次推进。
异或和表是什么呢?
xor 表示异或
即 若前俩个数是 2 3
异或和表就是 2 + 3 + 2xor3
为了体现异或的本质我们用二进制表示 即 10 + 11 + 01
那么 异或和表就是 22,即每一位上的1的个数,和的值就是221+2*20
如果我们再想插入一个3怎么操作呢
再加一个3的那么这个扩充的异或和本质 就是 2+3+2xor3+2xor3+3xor3+2xor3xor3+3
我们发现前三个数的和 就是前俩个数的异或和,所以异或和的递推只要每次+=就行
我们发现 新加3对异或和操作的本质就是3和这个异或和的每一个数再取异或然后求和
如果前俩个数的异或和表的第二位是2,那么就说明前面的异或和表2进制的第二位有俩个1
一共三个数,就说明有一个0,俩个1,3的第二位有1,那么3与前面的异或和再取异或后
二进制第二位会+= 前面参与异或和的数的个数-当前位1的个数 也就是3-2=1
所以二进制第二位的1的个数就是3了,当然我们最后还要加上3自己,那么最终第二位1的个数就是4
依次类推就可以把n个数全部假如到异或和表中来,对于前i个数组成的异或和表到底有多少个数呢
可以设置变量cnt = 0从0开始依次递推,每次cnt
2+1.
综上我们要遍历n个数,且每次遍历第i个数的时候还要遍历其二进制的每一位
也就是o(n*20)
注意这道题的数据范围 A<=2^20很关键,毕竟没有这个条件我们都不知道二进制要枚举多少位

posted @   希望上课能听懂  阅读(423)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示