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

    已知一个长度为n的正整数序列A(下标从1开始), 令 S = { x | 1 <= x <= n },

    S 的幂集2^S定义为S 所有子集构成的集合。

    定义映射 f : 2^S -> Z

    f(空集) = 0

    f(T) = XOR A[t](异或和)

     对于一切t属于T现在albus把2^S中每个集合的f值计算出来, 从小到大排成一行, 记为序列B(下标从1开始)。

    给定一个数, 那么这个数在序列B中第1次出现时的下标是多少呢?

    呃啊啊还我们一个可视的题面。

    这是个结论题。。。

    结论:

    n个数构成的线性基有k个时,那么这n个数的全部子集的异或和刚好就是线性基k个数能拼成的2k个数,每个数有2n-k个。

    证明也许比较显然?

    然后这题就可做了。

    好无聊。。。结论题什么的。。。

    但是有什么办法呢?只能记住吧。

    写这篇博客的目的就是为了存一下结论。

    以及推荐blog:rvalue

    里面有结论的感性证明。

    有了结论,代码倒挺好写的。

     1 #include<cstdio>
     2 #define mod 10086
     3 int pw(int b,int t,int a=1){for(;t;t>>=1,b=b*b%mod)if(t&1)a=a*b%mod;return a;}
     4 int base[33];
     5 int main(){
     6     int n,N,x,cnt=0,ans=0;scanf("%d",&n);N=n;
     7     while(n--){
     8         scanf("%d",&x);
     9         for(int i=30;~i;--i)if(!base[i]&&x&1<<i){base[i]=x;break;}
    10             else if(x&1<<i)x^=base[i];
    11     }
    12     scanf("%d",&x);
    13     for(int i=30;~i;--i)if(base[i]&&x&1<<i)cnt++,ans=(ans+pw(2,N-cnt))%mod;
    14         else if(base[i])cnt++;
    15     printf("%d
    ",ans+1);
    16     
    17 }
    View Code
  • 相关阅读:
    如何在winform的numericUpDown中显示小数点
    Jquery attr 和removeAttr 的简单使用
    Linux下的多进程编程初步(转载)
    扩展GCD和线性模方程组
    05、Flutter常用组件
    12、Flutter组件装饰
    10、Flutter资源和图片
    09、Flutter手势控制
    04、FlutterDart语法
    07、FluterCupertino
  • 原文地址:https://www.cnblogs.com/hzoi-DeepinC/p/11624654.html
Copyright © 2011-2022 走看看