感觉挺可做的但是不会..
\(k=1\)按位扫就好了 出现\(1\)概率就是\(0.5\)
\(k=2\)要特殊处理
设xor后的数是\(b_1 b_2 \dots b_n\)
计算平方贡献就好了\(\sum_{i,j}b_i b_j 2^{i+j}*p\)
\(p\)存在一位\(i\),\(j\)不同的话是1/4 否则就是1/2
\(k\geq3\)
首先要知道随机选数的话
如果维护的集合可以通过xor算子得到\(x\)
那么\(x\)与答案无关
维护一个大小为\(63 / 3 = 21\)的线性基
暴力枚举集合就好了
要注意中间的时候会爆long long
可能需要一些技巧(或者使用__int128
#include <bits/stdc++.h>
#define int long long
#define fo(i, n) for(int i = 1; i <= (n); i ++)
#define out(x) cerr << #x << " = " << x << "\n"
using namespace std;
// by piano
template<typename tp> inline void read(tp &x) {
x = 0; char c = getchar(); bool f = 0;
for(; c < '0' || c > '9'; f |= (c == '-'), c = getchar());
for(; c >= '0' && c <= '9'; x = (x << 3) + (x << 1) + c - '0', c = getchar());
if(f) x = -x;
}
const int N = 3e5 + 233;
int n, k, a[N];
#define ull unsigned long long
namespace sbt1 {
ull ans = 0;
void main(void) {
fo(i, n) ans |= a[i];
cout << (ans >> 1) << (ans & 1 ? ".5\n" : "\n");
}
}
namespace sbt2 {
ull ans = 0, tmp = 0, all = 0;
void main(void) {
fo(i, n) all |= a[i];
for(int k1 = 0; k1 < 32; k1 ++) {
for(int k2 = 0; k2 < 32; k2 ++)
if((all >> k1 & 1) && (all >> k2 & 1)) {
int has = 0;
fo(i, n) if((a[i] >> k1 & 1) ^ (a[i] >> k2 & 1)) {
has = 1;
break;
}
if(has) { // / 4
if(k1 + k2 <= 1)
tmp ++;
else ans += 1llu << (k1 + k2 - 2);
}
else { // / 2
if(k1 + k2 <= 0)
tmp ++;
else ans += 1llu << (k1 + k2 - 1);
}
}
}
ans += tmp >> 1;
cout << ans << (tmp & 1 ? ".5\n" : "\n");
}
}
namespace sbt3 {
#define LL __int128
int b[233];
int c[233], cnt = 0;
void main(void) {
for(int i = 1; i <= n; i ++) {
for(int k = 21; k >= 0; k --)
if(a[i] >> k & 1) {
if(!b[k]) {
b[k] = a[i];
break;
}
a[i] ^= b[k];
}
}
for(int k = 21; k >= 0; k --)
if(b[k])
c[cnt ++] = b[k];
LL ALL = (1ll << cnt);
LL ans = 0;
for(int st = 0; st < (1 << cnt); st ++) {
LL t = 0, p = 1;
for(int k = 0; k < cnt; k ++)
if(st >> k & 1)
t ^= (LL) (c[k]);
for(int i = 1; i <= k; i ++)
p *= t;
ans += p;
}
int t1 = ans % ALL;
int t2 = ans / ALL;
cout << t2 << (t1 ? ".5\n" : "\n");
}
}
main(void) {
read(n); read(k);
for(int i = 1; i <= n; i ++)
read(a[i]);
if(k == 1) sbt1::main();
else if(k == 2) sbt2::main();
else sbt3::main();
}
原文地址:https://www.cnblogs.com/foreverpiano/p/9215280.html
时间: 2024-10-11 16:39:03