Problem Description

Memphis loves xor very musch.Now he gets an array A.The length of A is n.Now he wants to know the sum of all (lowbit(Ai xor Aj) (i,j∈[1,n])
We define that lowbit(x)=2^k,k is the smallest integer satisfied ((x and 2^k)>0)
Specially,lowbit(0)=0

Because the ans may be too big.You just need to output ans mod 998244353

Input

Multiple test cases, the first line contains an integer T(no more than 10), indicating the number of cases. Each test case contains two lines
The first line has an integer n
The second line has n integers A1,A2....An
n∈[1,5∗10^4],Ai∈[0,2^29]

Output

For each case, the output should occupies exactly one line. The output format is Case #x: ans, here x is the data number begins at 1.

Sample Input

2

5

4 0 2 7 0

5

2 6 5 4 0

Sample Output

Case #1: 36

Case #2: 40

首先题目要求的lowbit自然是两数从后往前第一个非0位。

对于两个元素来说,亦或运算是相同为0,不同为1.

所以从最后一位往前考虑第一个不同位。

一开始想用set数组统计每位有0或1的集合,发现最后复杂度是O(n*n*logn)。。。果断是没想好。。。写了一半果断扔了。

后来对第一组样例手写后发现。

000

000

100

010

111

对于末尾是0的集合和末尾是1的集合,两集合间互相映射的元素必然亦或后取lowbit的结果是1。而集合内元素lowbit的结果必然不是1。

所以能通过最后一位亦或得到的lowbit个数就是两个集合元素个数的乘积。

这样这两个集合间运算的结果就有了,不需要再考虑了。

所以进行分治,接下来考虑集合内部的。对于某个集合内部,自然考虑倒数第二位元素是0的子集和倒数第二位是1的子集。同理这样递归定义下去。

然而这样的话两个元素间只计算了一次,而题目需要求两次,最终ans自然乘上2。

另外能进行上述操作的话,需要预先对数组进行按每一位的排序,这里采用了STL的sort,写了cmp函数。

然后用dfs进行搜索即可。

代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <set>
#include <map>
#include <queue>
#include <string>
#define LL long long
#define N 998244353 using namespace std; bool cmp(LL a, LL b)
{
while (a || b)
{
if ((a&) != (b&))
return (a&) < (b&);
a >>= ;
b >>= ;
}
return ;
} int n;
LL a[], ans; void dfs(int from, int to, int now)
{
if (now > )
return;
if (from >= to)
return;
int i;
for (i = from; i <= to; ++i)
{
if (a[i] & (<<now))
break;
}
LL x = i-from, y = to-i+;
ans += (((x*y)%N)*(<<now)) % N;
ans %= N;
dfs(from, i-, now+);
dfs(i, to, now+);
} void input()
{
scanf("%d", &n);
for (int i = ; i < n; ++i)
scanf("%I64d", &a[i]);
sort(a, a+n, cmp);
ans = ;
} int main()
{
//freopen("test.in", "r", stdin);
int T;
scanf("%d", &T);
for (int times = ; times <= T; ++times)
{
printf("Case #%d: ", times);
input();
dfs(, n-, );
ans = (*ans) % N;
printf("%I64d\n", ans);
}
return ;
}

最新文章

  1. Qt 静态编译后的exe太大, 可以这样压缩.
  2. Spring Remoting: Remote Method Invocation (RMI)--转
  3. C#, float.ToString()的一个坑
  4. oracle 用户 多个表空间
  5. POJ 2112 - Optimal Milking
  6. UVa572 Oil Deposits DFS求连通块
  7. Maven配置 settings.xml 转
  8. asp.net页面刷新等问题
  9. Qt编程之实现在QFileDialog上添加自定义的widget
  10. Week 5a - Mouse input and more lists----learning notes
  11. Android开发中碰到的一个ANR问题。
  12. 包建强的培训课程(7):iOS企业级开发实战
  13. android( java) 处理 null 和 预防空指针异常(NullPointerException) 的一些经验。
  14. 使用phpqrcode生成二维码
  15. [工具]Sublime 显示韩文
  16. HBase在搜狐内容推荐引擎系统中的应用
  17. Ubuntu12.04编译vlc-android详细流程
  18. IECapt、CutyCapt 生成网页快照
  19. Java:内存泄露和内存溢出
  20. 【51Nod 1239】欧拉函数之和

热门文章

  1. slam cartographer 学习
  2. Django--分页、session
  3. struts2 文件上传和下载,以及部分源代码解析
  4. 有一个长为n的数组A,求满足0≤a≤b&lt;n的A[b]-A[a]的最大值。 给定数组A及它的大小n,请返回最大差值。
  5. linux下网卡绑定
  6. mnesia的脏写和事物写的测试
  7. MongoDB的选举过程(转)
  8. 02 redis通用命令操作
  9. FPGA学习记录 - Quartus II 未使用管脚设置为三态输入
  10. OIer同样是音乐家