zoukankan      html  css  js  c++  java
  • 【线性基】bzoj2844: albus就是要第一个出场

    线性基求可重rank

    题目描述

    给定 n 个数 ${ a_i }$ ,以及数 $x$。

    将 ${ a_i }$​ 的所有子集(包括空集)的异或值从小到大排序,得到 ${ b_i } $。

    求 $x$ 在 ${ b_i }$ 中第一次出现的下标。保证 $x$ 在 ${ b_i }$ 中出现。

    HINT

    数据范围:

    1 <= N <= 10,0000

    其他所有输入均不超过10^9


    题目分析

    考虑线性基求rank的过程,是一个求第k大的逆过程。也就是首先对线性基消元,再把线性基的元素给排出来,继而考虑每一位被线性基内第几个元素控制。

    而现在是一个可重集,于是{1,1}和{1,1,1,1,1}就成了截然不同的两种情况。记线性基内有$legal$个元素,那么剩下就是$n-legal$个可被线性基表示的数字(下面简称无关数字)。沿用线性基题的一类思维方式,考虑这类无关数字对于线性基的影响。我们会发现,不论选出哪一部分无关数字(共$2^{n-legal}$种情况),都有且仅有一种“在线性基内选数”的方式使得选出的无关数字被重新异或为0.也就是说,记原rank为$preRank$,可重集rank就是$preRank*2^{n-legal}+1$。

    对了,求原rank时候记得要和第k大操作一样把线性基元素重新拎出来。

     1 #include<bits/stdc++.h>
     2 const int maxn = 100035;
     3 const int MO = 10086;
     4 
     5 int n,p[103],ans,legal;
     6 
     7 int read()
     8 {
     9     char ch = getchar();
    10     int num = 0, fl = 1;
    11     for (; !isdigit(ch); ch = getchar())
    12         if (ch=='-') fl = -1;
    13     for (; isdigit(ch); ch = getchar())
    14         num = (num<<1)+(num<<3)+ch-48;
    15     return num*fl;
    16 }
    17 void insert(int x)
    18 {
    19     for (int i=30, chk=0; i>=0&&!chk; i--)
    20         if (x>>i){
    21             if (p[i]) x ^= p[i];
    22             else{
    23                 p[i] = x, chk = 1, ++legal;
    24                 for (int j=30; j>i; j--)
    25                     if (p[j]>>i) p[j] ^= p[i];
    26             } 
    27         }
    28 }
    29 void query(int x)
    30 {
    31     int i,j;
    32     for (i=0, j=0; i<=30; i++)
    33         if (p[i]) p[j] = i, ++j;
    34     for (i=j-1; i>=0; i--)
    35         if ((1<<p[i])&x) ans += (1<<i);
    36 }
    37 int qmi(int a, int b)
    38 {
    39     int ret = 1;
    40     for (a%=MO; b; b>>=1, a=a*a%MO)
    41         if (b&1) ret = ret*a%MO;
    42     return ret;
    43 }
    44 int main()
    45 {
    46     n = read();
    47     for (int i=1; i<=n; i++) insert(read());
    48     query(read());
    49     ans = (1ll*ans*qmi(2, n-legal)%MO+1)%MO;
    50     printf("%d
    ",ans);
    51     return 0;
    52 } 

    END

  • 相关阅读:
    webstorm9.0.3 注册码
    SpringMVC 文件上传下载
    Nginx解决post请求405问题
    nginx配置Strict Transport Security
    MySQL修改max_allowed_packet
    ELK批量删除索引
    ELK出现unassigned_shards查看及删除
    Nagios监控mysql主从复制
    Linux DNS原理简介及配置
    root密码重置(Centos 7)
  • 原文地址:https://www.cnblogs.com/antiquality/p/10203436.html
Copyright © 2011-2022 走看看