线性基 uoj 36 清华集训2014 玛里苟斯

Posted foreverpiano

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线性基 uoj 36 清华集训2014 玛里苟斯相关的知识,希望对你有一定的参考价值。

http://uoj.ac/problem/36

感觉挺可做的但是不会..

(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

(kgeq3)

首先要知道随机选数的话

如果维护的集合可以通过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
" : "
");  
  }
}

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
" : "
");
  }
}

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
" : "
");
  }
}

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();

}

以上是关于线性基 uoj 36 清华集训2014 玛里苟斯的主要内容,如果未能解决你的问题,请参考以下文章

[UOJ]#36. 清华集训2014玛里苟斯

uoj 36 玛里苟斯

清华集训2014玛里苟斯

bzoj 3811 玛里苟斯 - 线性基

[毒瘤题]玛里苟斯:线性基,表达式分析,测试点分治

BZOJ 3811玛里苟斯 大力观察+期望概率dp+线性基