线性基 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

\(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-08-05 09:51:48

线性基 uoj 36 清华集训2014 玛里苟斯的相关文章

uoj #46[清华集训2014]玄学

uoj 因为询问是关于一段连续区间内的操作的,所以对操作构建线段树,这里每个点维护若干个不交的区间,每个区间\((l,r,a,b)\)表示区间\([l,r]\)内的数要变成\(ax+b\) 每次把新操作加入线段树中下一个叶子,然后如果某个节点里所有操作都加进去了,就条到父亲,把两个儿子的信息合并到父亲上.这里合并就是把两个区间集合合并成一个,例如两个区间\([a,c]\)和\([b,d](a\le b\le c\le d)\)会合并成\([a,b),[b,c),[c,d]\).合并出来的区间如果

bzoj 3816&amp;&amp;uoj #41. [清华集训2014]矩阵变换

稳定婚姻问题: 有n个男生,n个女生,所有女生在每个男生眼里有个排名,反之一样. 将男生和女生两两配对,保证不会出现婚姻不稳定的问题. 即A-1,B-2 而A更喜欢2,2更喜欢A. 算法流程: 每次男生向自己未追求过的排名最高女生求婚. 然后每个有追求者的女生在自己现男友和追求者中选择一个最喜欢的接受,然后拒绝其他人. 算法一定可以结束. 因为如果最后有一个男生单身,那他一定把所有女生都追求过一遍,说明没有女生单身,产生矛盾. #include<iostream> #include<cs

UOJ.41.[清华集训2014]矩阵变换(稳定婚姻)

题目链接 稳定婚姻问题:有n个男生n个女生,每个男/女生对每个女/男生有一个不同的喜爱程度.给每个人选择配偶. 若不存在 x,y未匹配,且x喜欢y胜过喜欢x当前的配偶,y喜欢x也胜过y当前的配偶 的完备匹配,则称这是一个稳定匹配. 稳定匹配一定存在,且存在一个\(O(n^2)\)的算法: 任选一个未匹配的男生x,按x的喜爱程度从大到小枚举每个女生,若当前女生没有配偶或喜欢x胜过喜欢当前配偶,则与x匹配.直到所有男生都匹配. 这一题我们用行表示男生,n个数表示女生.喜爱程度为:行更喜欢靠前的数,数

uoj 41 【清华集训2014】矩阵变换 婚姻稳定问题

[清华集训2014]矩阵变换 Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://uoj.ac/problem/41 Description 给出一个 N 行 M 列的矩阵A, 保证满足以下性质: M>N.    矩阵中每个数都是 [0,N] 中的自然数.    每行中, [1,N] 中每个自然数都恰好出现一次.这意味着每行中 0 恰好出现 M−N 次.    每列中,[1,N] 中每个自然数至多出现一次. 现在我们要在每行中选取一个非零数,

AC日记——【清华集训2014】奇数国 uoj 38

#38. [清华集训2014]奇数国 思路: 题目中的number与product不想冲: 即为number与product互素: 所以,求phi(product)即可: 除一个数等同于在模的意义下乘以一个数的逆元: 代码: #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define maxn 100005

清华集训2014 做题记录

清华集训2014做题记录 已完成 [清华集训2014]玛里苟斯 [清华集训2014]主旋律 [清华集训2014]奇数国 [清华集训2014]矩阵变换 [清华集训2014]sum [清华集训2014]虫逢 [清华集训2014]玄学 [清华集训2014]文学 未完成 [清华集训2014]卡常数 [清华集训2014]简单回路 [清华集训2014]Router [清华集训2014] Breaking Bomber 写一题要膜一题题解,膜完题解膜代码,膜完代码膜指导,膜了好几天了还有四个题没做. [清华集

「清华集训2014」主旋律

「清华集训2014」主旋律 这个题好难难啊,我想了一个小时连50分都不会,只能去摸周指导了. 我们试图直接爆算集合 \(S\) 的非强连通导出子图数量,考虑将这个导出子图的所有强连通分量缩点后,一定是一个点数 \(\geq 2\) 的 \(\text{DAG}\) .即缩完以后至少要有一个入度为 \(0\) 的点,这个条件充分性显然,必要性考虑如果不存在入度为 \(0\) 的点,那么一定存在一个环,说明并没有将所有强连通分量缩掉.然后我们枚举入度为 \(0\) 的点集 \(T\) ,记 \(F(

「清华集训2014」矩阵变换

「清华集训2014」矩阵变换 解题思路 问题转化为找一个行与选的数字的完美匹配,记 \(pos[i][j]\) 为数字 \(i\) 在第 \(j\) 行的出现位置,要求不存在匹配边 \((a,b),(c,d)\) 使得 \(pos[b][a] < pos[b][c]\ \& \ pos[d][c] > pos[b][c]\) . 观察发现,这个式子相当于让一条边的权值看做 \(pos[x][y]\) ,当存在一个行与一个数没有匹配但是强行让它们匹配后数的权值会变大,行的权值会变小,这个

UOJ#36. 【清华集训2014】玛里苟斯 线性基

原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ36.html 题解 按照 $k$ 分类讨论: k=1 : 我们考虑每一位的贡献.若有至少一个数第 $i$ 位为 $1$ ,则对答案的贡献为 $2^i/2$ . k=2 : 发现每个异或和的平方为 $\sum_i\sum_j2^{i+j}bit_ibit_j$.那么考虑第 $i$ 位和第 $j$ 位的积的期望值.如果所有的数中,第 $i$ 位和第 $j$ 位均相等且非全零,那么参考 k=1 的情况,期望为