zoukankan      html  css  js  c++  java
  • bzoj 2844 albus就是要第一个出场

    题目传送门

      这是个通往vjudge的虫洞

      这是个通往bzoj的虫洞

    题目大意

      给定集合$S$,现在将任意$Asubseteq S$中的元素求异或和,然后存入一个数组中(下标从1开始),然后从小到大排一个序。问$q$第一次出现在$A$中的下标。

      我们可以通过线性基得到值域上有多少个异或和比$q$小,现在问题来了,怎么求$q$的下标。

      通过打表找规律,以及手动枚举可以发现一个结论。

    定理1 设线性基为$B$,那么在$S$的子集的异或和中,出现的异或和的出现的次数是$2^{left | S ight |- left | mathfrak{B} ight |} $。

      证明 假如要考虑异或出一个数$x$,基外选出的数的异或和为$s$,那么还需要$x$ ^ $s$,对于它,基内的线性表示的方法是唯一的。

      所以定理得证。

      于是再做一次快速幂,这道题就做完了。

      PS:这道题数据有错,它没有保证$q$一定能被异或出来

    Code

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef bool boolean;
     4 
     5 const int MAX_BASE = 31, M = 10086; 
     6 
     7 int qpow(int a, int pos) {
     8     int pa = a, rt = 1;
     9     for ( ; pos; pos >>= 1, pa = pa * pa % M)
    10         if (pos & 1)
    11             rt = rt * pa % M;
    12     return rt;
    13 }
    14 
    15 int n, q;
    16 int *ar;
    17 int b[MAX_BASE];
    18 int s[MAX_BASE];
    19 
    20 inline void init() {
    21     scanf("%d", &n);
    22     ar = new int[(n + 1)];
    23     for (int i = 1; i <= n; i++)
    24         scanf("%d", ar + i);
    25     scanf("%d", &q);
    26 }
    27 
    28 int cnt = 0, rk = 0;
    29 inline void solve() {
    30     for (int i = 1; i <= n; i++) {
    31         for (int j = MAX_BASE - 1; ~j; j--) {
    32             if (ar[i] & (1 << j))    ar[i] ^= b[j]; 
    33             if (ar[i] & (1 << j)) {
    34                 b[j] = ar[i];
    35                 cnt++;
    36                 break;
    37             }
    38         }
    39     }
    40     for (int i = 0; i < MAX_BASE; i++)
    41         if (b[i])
    42             s[i] = 1;
    43     for (int i = 0; i < MAX_BASE; i++)
    44         s[i] += s[i - 1];
    45     for (int i = MAX_BASE - 1; ~i; i--)
    46         if ((q & (1 << i)) && b[i])
    47             rk |= (1 << (s[i] - 1));
    48     printf("%d
    ", ((rk % M) * qpow(2, n - cnt) + 1) % M);
    49 }
    50 
    51 int main() {
    52     init();
    53     solve();
    54     return 0;
    55 }
  • 相关阅读:
    [JLOI2015]管道连接
    [TJOI2015]旅游
    [TJOI2015]组合数学
    [CSP-S2019] 树上的数
    [NOI2020] 超现实树
    1:关于证书服务器
    vue:实现竖向滚动条效果并实现锚点定位跳转
    修改ElementUI的样式----vue如何控制步骤条steps圆圈的大小 data-v-
    PyCharm 查看变量值
    PyCharm 单步执行单步调试不能停到断点
  • 原文地址:https://www.cnblogs.com/yyf0309/p/8502941.html
Copyright © 2011-2022 走看看