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
// 拆位就好了