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

    就是我代码里读入之后的那一部分。

    1.(一下a[]为原数组 a'[]为线性基)

    线性基 中的a'[i]其实 是 原来的a[]中的某个子集(2^n个子集中的某个) 异或出来的  可能会有其他的子集与它异或和相同,a'[i]代表了 这个集合。

    线性基的大小是log的,因为  a[]中异或和等于a'[i]的集合可能有好多   而线性基则 通过异或消掉了这些 重复的。

    2.

    假设a[]大小为n  线性基大小为k,则a[]和a'[] 都有且仅有2^k种 异或和不同 的子集【清楚线性基定义的话 这是显然的】

    然而由于本题 要保留重复的, 那么另一个性质就是 a'[]可异或出的2^k种异或和  在a[]可异或出的2^n个有重复的值中 每个不同的值都有2^(n-k)个。

    所以最后ans要*2^(n-k) 

     1 #include <bits/stdc++.h>
     2 #define mo 10086
     3 using namespace std;
     4 int b[50],a[100005],n,m,k,t,x,y,z,p,q,ans;
     5 int main(){
     6     scanf("%d",&n);
     7     for (int i=1;i<=n;++i) scanf("%d",&a[i]);
     8     scanf("%d",&m); k=0;
     9     for (int i=1<<29;i;i>>=1){
    10         for (int j=k+1;j<=n;++j)
    11         if (a[j]&i){
    12             swap(a[j],a[++k]); b[k]=i;
    13             for (int o=1;o<=n;++o)
    14             if (o!=k&&a[o]&i) a[o]^=a[k];
    15             break;
    16         }
    17     }
    18     for (int i=1;i<=k;++i)
    19     if ((x^a[i])<=m){
    20         x^=a[i];
    21         (ans+=(1<<k-i)%mo)%=mo;
    22     }
    23     for (int i=k+1;i<=n;++i) (ans<<=1)%=mo;
    24     ++ans%=mo; printf("%d",ans);
    25     return 0;
    26 }
    Archer
  • 相关阅读:
    [ SDOI 2006 ] 保安站岗
    [ TJOI 2012 ] 防御
    [ ZJOI 2012 ] 灾难
    [ HNOI 2008 ] 玩具装箱
    「UER#2」信息的交换
    「UR#5」怎样跑得更快
    「UR#6」懒癌
    清华集训2014 做题记录
    「UR#5」怎样更有力气
    弦图及区间图学习笔记
  • 原文地址:https://www.cnblogs.com/cyz666/p/6516458.html
Copyright © 2011-2022 走看看