HDU-5269 ZYB loves Xor I

倾然丶 夕夏残阳落幕 提交于 2020-03-08 13:25:55

题目大意:

给出一个长度为n的数组A,让你求出lowbit(A[i]^A[j])的和对998244353取模的结果,其中i和j都属于[1,n]。lowbit(x)表示的是满足x xor 2^k > 0最小的2^k

解题思路:

因为数据规模很明显是5e4这样的规模,直接暴力搞必然超时,那么我们可以考虑一个问题,对于异或,如果x xor 2^k > 0的话,k一定是x二进制表示中最小的一位为1的数。

知道了这个还是无法求出来这个问题。因为涉及到异或问题,所以我们很容易想到字典树,字典树第h层的左子树表示数据自右向左第h位为0的,右子树表示第h位为1。

而这两个如果同时存在,那么这两个节点当前能表示的数的个数的乘积乘以1 << h就是这两个节点能表示的数的lowbit值。

最后答案乘以2即可。

代码:

#include <cstring>
#include <iostream>
using namespace std;

typedef struct node {
	int val;
	int nxt[2];
}Trie;

const int maxn = 50005;
const int mod = 998244353;

int tot;
Trie t[maxn * 30];

void Insert(int x) {
	int tmp, p = 0;
	for (int i = 0; i < 30; ++i) {
		if (x & (1 << i)) tmp = 1;
		else tmp = 0;
		if (!t[p].nxt[tmp]) {
			t[tot].val = t[tot].nxt[0] = t[tot].nxt[1] = 0;
			t[p].nxt[tmp] = tot++;
		}
		p = t[p].nxt[tmp];
		++t[p].val;
	}
}
int query(int p, int h) {
	int lef = t[p].nxt[0];
	int rig = t[p].nxt[1];
	long long tmp = (((long long)t[lef].val * (long long)t[rig].val) % mod * (1 << h)) % mod;
	if (lef) tmp = (tmp + query(lef, h + 1)) % mod;
	if (rig) tmp = (tmp + query(rig, h + 1)) % mod;
	return tmp;
}
int main() {
	ios::sync_with_stdio(false); cin.tie(0);
	int n, x, T; cin >> T;
	for (int cas = 1; cas <= T; ++cas) {
		cin >> n; tot = 1;
		t[0].val = t[0].nxt[0] = t[0].nxt[1] = 0;
		for (int i = 0; i < n; ++i) {
			cin >> x;
			Insert(x);
		}
		long long ans = query(0, 0);
		ans = (2 * ans) % mod;
		cout << "Case #" << cas << ": " << ans << endl;
	}
	return 0;
}


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!