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

    题意:给你一个数列A。将所有可能异或出的值从小到大排列。问x是第几个。ai<=1e9,n<=100000.

    标程:

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 using namespace std;
     5 typedef long long ll;
     6 const int mod=10086;
     7 int cnt[32],n,x,tot,s[32],ans;
     8 void ins(int x)
     9 {
    10     for (int i=31;i>=0;i--)
    11       if ((x>>i)&1)
    12         if (!cnt[i]) {cnt[i]=x;break;}
    13         else  x^=cnt[i];
    14 }
    15 int ksm(int x,int y)
    16 {
    17     int res=1;
    18     while (y) {if (y&1) res=(ll)res*x%mod; x=(ll)x*x%mod; y>>=1;}
    19     return res;
    20 }
    21 int main()
    22 {
    23     scanf("%d",&n);
    24     for (int i=1;i<=n;i++) scanf("%d",&x),ins(x);
    25     for (int i=0;i<=31;i++)
    26       if (cnt[i]) tot++,s[i]=tot;
    27     int d=ksm(2,n-tot);
    28     scanf("%d",&x);
    29     for (int i=31;i>=0;i--)
    30       if (((x>>i)&1)&&s[i]) ans=((ll)ans+(1<<s[i]-1))%mod;
    31     ans=(ll)ans*d%mod;
    32     printf("%d
    ",(ans+1)%mod);
    33    return 0;
    34 }

    题解:线性基

    用映射可证每一个可能被异或出的值出现2^(n-线性基元素个数),最后乘一下即可。

    在线性基中进行消元,那么每一位的1只有可能在线性基的一个位置上。异或出一个数相当于在位置上增加1。

    询问的x若能用s1^s2^s3^...^sk表示,那么可以用:不取最高位,其他任取;取最高位,第二位不取,其他任取;取最高位第二位,不取第三位,其他任取,……这样统计出能够异或出的互不相同的<x的值有多少个。也就是对于该位在x中是1且存在的每一个线性基统计。

  • 相关阅读:
    C#之类和对象
    uml中关联与依赖
    uml中的各个关系
    数据挖掘聚类算法分类(转)
    (转)Client http persistent connection limit
    牛客网NOIP赛前集训营提高组(第七场)Solution
    训练题表
    CF1000赛后总结
    UVA3983 Robotruck 题解
    CF1034A Enlarge GCD
  • 原文地址:https://www.cnblogs.com/Scx117/p/8716167.html
Copyright © 2011-2022 走看看