• bzoj2884 albus就是要第一个出场


    Description

    已知一个长度为n的正整数序列A(下标从1开始), 令 S = { x | 1 <= x <= n }, S 的幂集2^S定义为S 所有子集构成的集合。定义映射 f : 2^S -> Zf(空集) = 0f(T) = XOR A[t] , 对于一切t属于T现在albus把2^S中每个集合的f值计算出来, 从小到大排成一行, 记为序列B(下标从1开始)。 给定一个数, 那么这个数在序列B中第1次出现时的下标是多少呢?

    Input

    第一行一个数n, 为序列A的长度。接下来一行n个数, 为序列A, 用空格隔开。最后一个数Q, 为给定的数.

    Output

    共一行, 一个整数, 为Q在序列B中第一次出现时的下标模10086的值.

    Sample Input

    3
    1 2 3
    1

    Sample Output

    3
    样例解释:
    N = 3, A = [1 2 3]
    S = {1, 2, 3}
    2^S = {空, {1}, {2}, {3}, {1, 2}, {1, 3}, {2, 3}, {1, 2, 3}}
    f(空) = 0
    f({1}) = 1
    f({2}) = 2
    f({3}) = 3
    f({1, 2}) = 1 xor 2 = 3
    f({1, 3}) = 1 xor 3 = 2
    f({2, 3}) = 2 xor 3 = 1
    f({1, 2, 3}) = 0
    所以
    B = [0, 0, 1, 1, 2, 2, 3, 3]

    HINT

    数据范围:
    1 <= N <= 10,0000
    其他所有输入均不超过10^9

    正解:线性基。

    题意就很绕。。给定一个序列,任意异或得到一个新的序列,并把序列排序。再给定一个Q,求Q在新序列中的排名。

    然后我就不会做了。看了题解才知道线性基原来还有一个神奇的性质。

    n个数的序列共有$2^{n}$种异或和,n个数的线性基共有k个数,所以n个数的线性基共有$2^{k}$种不同的异或和。神奇的是,$2^{k}$不同的异或和在$2^{n}$种异或和中出现的次数竟然相同,都是$2^{n-k}$次!

    所以,我们只要算出线性基中异或和小于Q的数的个数,然后乘上$2^{n-k}$,再加上1,这个就是答案了。

     1 //It is made by wfj_2048~
     2 #include <algorithm>
     3 #include <iostream>
     4 #include <complex>
     5 #include <cstring>
     6 #include <cstdlib>
     7 #include <cstdio>
     8 #include <vector>
     9 #include <cmath>
    10 #include <queue>
    11 #include <stack>
    12 #include <map>
    13 #include <set>
    14 #define inf (1<<30)
    15 #define rhl (10086)
    16 #define N (100010)
    17 #define il inline
    18 #define RG register
    19 #define ll long long
    20 #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
    21 
    22 using namespace std;
    23 
    24 vector <int> Q;
    25 
    26 int a[N],p[35],n,q,rk,cnt;
    27 
    28 il int gi(){
    29     RG int x=0,q=1; RG char ch=getchar(); while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
    30     if (ch=='-') q=-1,ch=getchar(); while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar(); return q*x;
    31 }
    32 
    33 il void insert(RG int x){
    34     for (RG int i=30;i>=0;--i)
    35     if (x&(1<<i)){
    36         if (!p[i]){ p[i]=x; break; }
    37         x^=p[i];
    38     }
    39     return;
    40 }
    41 
    42 il int qpow(RG int a,RG int b){
    43     RG int ans=1;
    44     while (b){
    45     if (b&1) ans=ans*a%rhl;
    46     a=a*a%rhl,b>>=1;
    47     }
    48     return ans;
    49 }
    50 
    51 il void work(){
    52     n=gi(); for (RG int i=1;i<=n;++i) a[i]=gi(),insert(a[i]); q=gi();
    53     for (RG int i=0;i<=30;++i) if (p[i]) Q.push_back(i),cnt++;
    54     for (RG int i=0;i<Q.size();++i) if (q&(1<<Q[i])) rk+=1<<i;
    55     printf("%d
    ",(rk%rhl*qpow(2,n-cnt)%rhl+1)%rhl);
    56     return;
    57 }
    58 
    59 int main(){
    60     File("albus");
    61     work();
    62     return 0;
    63 }
  • 相关阅读:
    Linux 网络流量实时监控工具之ntopng详解
    linux wget 命令用法详解(附实例说明)
    Linux curl使用简单介绍
    数据库中随机查询数据
    【算法】验证码识别基础方法及源码(转)
    CentOS 7静默(无图形化界面)安装Oracle 11g
    史上最详细最全的Linux上安装Oracle的教程-centos7
    如何实现Docker镜像和容器实例的备份迁移
    oozie timezone时区配置
    通过hue提交oozie定时任务
  • 原文地址:https://www.cnblogs.com/wfj2048/p/6546710.html
Copyright © 2020-2023  润新知