求助 WA on #15
  • 板块CF241B Friends
  • 楼主liuzimingc
  • 当前回复1
  • 已保存回复1
  • 发布时间2024/7/26 20:51
  • 上次更新2024/7/26 22:23:04
查看原帖
求助 WA on #15
421781
liuzimingc楼主2024/7/26 20:51

RT。并不知道为什么。求助大佬(((

#include <bits/stdc++.h>
 
using namespace std;

namespace liuzimingc {
#define endl '\n'
const int N = 1e6 + 5, MOD = 1e9 + 7, inv2 = 500000004;

int n, m, a[N], nxt[N][2], siz[N], tot = 1, sum, cnt[N][31];
long long ans;

void insert(int x) {
	int now = 1;
	for (int i = 30; ~i; i--) {
		int p = x >> i & 1;
		if (!nxt[now][p]) nxt[now][p] = ++tot;
		now = nxt[now][p];
		siz[now]++;
	}
}

int ask(int x, int mid) {
	int now = 1, res = 0;
	sum = 0;
	for (int i = 30; ~i; i--) {
		int p = x >> i & 1;
		if (!(mid >> i & 1)) res += siz[nxt[now][p ^ 1]], now = nxt[now][p];
		else now = nxt[now][p ^ 1];
	}
	res += siz[now];
	return res;
}

long long check(int mid) {
	long long ans = 0;
	for (int i = 1; i <= n; i++) ans += ask(a[i], mid);
	return ans >> 1;
}

void build(int x, int dep, int num) { // the number it represents
	if (!x) return;
	if (dep == -1) {
		for (int i = 0; i <= 30; i++)
			if (num >> i & 1) cnt[x][i] = siz[x];
		return;
	}
	build(nxt[x][0], dep - 1, num);
	build(nxt[x][1], dep - 1, num | (1 << dep));
	for (int i = 0; i <= 30; i++)
		cnt[x][i] = cnt[nxt[x][0]][i] + cnt[nxt[x][1]][i];
}

int get(int x, int mid) {
	int now = 1, ans = 0;
	for (int i = 30; ~i; i--) {
		int p = x >> i & 1;
		if (!(mid >> i & 1)) {
			// 统计 1,跳到 0
			// 你他妈不拆位统计你直接统计 delta 呢
			for (int j = 0; j <= 30; j++)
				if (x >> j & 1) ans += (siz[nxt[now][p ^ 1]] - cnt[nxt[now][p ^ 1]][j]) << j;
				else ans += cnt[nxt[now][p ^ 1]][j] << j;
			now = nxt[now][p];
		}
		else now = nxt[now][p ^ 1];
	}
	ans += siz[now] * mid;
	return ans;
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	cin >> n >> m;
	for (int i = 1; i <= n; i++) cin >> a[i], insert(a[i]);
	int l = 0, r = 1 << 30;
	while (l < r) {
		int mid = (long long)l + r + 1 >> 1;
		if (check(mid) >= m) l = mid;
		else r = mid - 1;
	}
	build(1, 30, 0);
	for (int i = 1; i <= n; i++) ans += get(a[i], l);
	(ans *= inv2) % MOD;
	cout << (ans - (long long)(check(l) - m) * l % MOD + MOD) % MOD << endl; // 处理重复情况
	return 0;
	
}
#undef int
} // namespace liuzimingc
    
int main() {
	liuzimingc::main();
	return 0;
}
// 不能直接维护和,因为 (x + y) xor z 不一定等于 x xor z + y xor z
// 拆位就好了
2024/7/26 20:51
加载中...