题目链接

分析:
这道题是hdu3949的逆运算(可能题面有点难懂)

既然我们能够知道排名是第k的数是多少
就可以直接二分,变成判定性问题

当然,这道题还有其他解法:

因为是子集异或和,可以考虑用线性基解决
把每一个数看成是一个向量,求出线性基
线性基是一个极小集:能够张成原空间的最小线性不相关向量集
那么任何一个异或和都可以用线性基得到

但是题目中会计算重复的数值,而线性基是不会计算重复元素的
我们先不考虑重复数字的问题

我们先回顾一下hdu3949的思路:

把k二进制拆分,如果k的第i位上是1,ans^=b[i]
虽然是^=b[i],然而由于矩阵是对角线型的,实际上就等价于ans+=b[i]

我们可以通过上面的过程得到ta的逆算法:

一共有nnn个数字,得到了k" role="presentation" style="position: relative;">kkk个线性基
注意:要使用此方法,要把矩阵消成对角线

我们举一个简单点的例子解释一下算法:

n=3
a: 3 4 7

我们得到的线性基是这样的:

i      2 1 0
B[2]   1 0 0   =4
B[1]   0 1 0   =2
B[0]   0 0 1   =1

现在我们要查找X=5X=5X=5的排名kkk
我们先想想,已知k" role="presentation" style="position: relative;">kkk的情况下,如何得到XXX:
显然,把k" role="presentation" style="position: relative;">kkk二进制分解后,如果第iii位是1,那么X+=b[i]" role="presentation" style="position: relative;">X+=b[i]X+=b[i]X+=b[i]

那么我们先把XXX二进制分解了:X=(101)2=22+20" role="presentation" style="position: relative;">X=(101)2=22+20X=(101)2=22+20X=(101)_2=2^2+2^0
我们找到B[x]=22,B[y]=20B[x]=22,B[y]=20B[x]=2^2,B[y]=2^0的x,yx,yx,y
k=2x+2yk=2x+2yk=2^x+2^y

这里我们需要解释一下以上所说的B的含义:去除0后的b数组
例如:
b={1,2,0,0,16,0,64}
B={1,2,16,64}
b和B不是一个回事!!!

之后我们就可以考虑重复的问题了:

  • 如果一个元素能够插入到在线性基中,则说明ta一定能为线性基贡献一个1
  • 如果一个元素不能插入线性基,则说明ta一定能用若干个线性基组合而成

设我们得到线性基的大小为kkk
则一共有n−k" role="presentation" style="position: relative;">n−kn−kn-k个数对线性基没有贡献
那么这些数加入之后对异或和没有影响:可以直接视为0

对于任意一个数iii的线性组合,我们可以随便选几个0加进去
那么i" role="presentation" style="position: relative;">iii的重复次数就是:2n−k2n−k2^{n-k}

因为可以有空集,所以0肯定会出现

我们可以先计算小于等于X−1X−1X-1的数字数量,加上1就得到了XXX的第一个出现位置

但是在代码实现中:

scanf("%d",&x);
int ans=0;
int tmp=cnt;
for (int i=31;i>=0;i--) if (b[i]) {if (x>>i&1) {      ans=ans+(1LL<<(tmp-1))*e[n-cnt]%p;ans%=p;}tmp--;}
ans++; ans%=p;

按理来说,应该在一开始:x- -
但是减掉1之后,将X二进制分解完,最后还要加上0的重复次数2n−k" role="presentation" style="position: relative;">2n−k2n−k2^{n-k}
所以我们就不用麻烦这一步啦

tip

不要忘了取模

WA了几次
问题就在于这个重复次数:2n−k2n−k2^{n-k}
n-k是可以高达1e5,所以我们只能在一开始预处理出2i(mod)p2i(mod)p2^i(mod)p的值:

for (int i=1;i<=n;i++) e[i]=(e[i-1]<<1)%p;
#include<bits/stdc++.h>
#define ll long longusing namespace std;const int N=100005;
const int p=10086;
int n,x,a[N],b[100],e[N];void cal() {for (int i=1;i<=n;i++) for (int j=31;j>=0;j--) if (a[i]>>j&1) {if (b[j]) a[i]^=b[j];else {b[j]=a[i];for (int k=j-1;k>=0;k--)if (b[k]&&(b[j]>>k&1)) b[j]^=b[k];for (int k=j+1;k<=31;k++)if (b[k]>>j&1) b[k]^=b[j];break;}}
}int main()
{scanf("%d",&n);e[0]=1;for (int i=1;i<=n;i++) e[i]=(e[i-1]<<1)%p;for (int i=1;i<=n;i++) scanf("%d",&a[i]);cal();int cnt=0;for (int i=0;i<=31;i++) if (b[i])cnt++;scanf("%d",&x);int ans=0;//有空集,0肯定会出现int tmp=cnt;for (int i=31;i>=0;i--) if (b[i]) {if (x>>i&1) {      ans=ans+(1LL<<(tmp-1))*e[n-cnt]%p;ans%=p;}tmp--;} ans++; ans%=p;printf("%d\n",ans);return 0;
}

bzoj2844 albus就是要第一个出场(线性基【询问排名)相关推荐

  1. BZOJ2844: albus就是要第一个出场(线性基)

    Time Limit: 6 Sec  Memory Limit: 128 MB Submit: 2054  Solved: 850 [Submit][Status][Discuss] Descript ...

  2. 【BZOJ2844】albus就是要第一个出场——线性基

    Time Limit: 6 Sec Memory Limit: 128 MB Description 已知一个长度为n的正整数序列A(下标从1开始), 令 S = { x | 1 <= x &l ...

  3. 【BZOJ2844】albus就是要第一个出场 线性基 高斯消元

    #include <stdio.h> int main() {puts("转载请注明出处[vmurder]谢谢");puts("网址:blog.csdn.ne ...

  4. [BZOJ2844]albus就是要第一个出场(线性基)

    题目: 我是超链接 题解: 先不考虑重复数字的问题,如果要求数字Q的出现位置的话,首先一个比较直观的想法是,如果能求出这样一组基底,它从小到大排序以后可以满足:设只选i向量构造出来的数字为R,那么1. ...

  5. 【bzoj2844 albus就是要第一个出场】

    题意:给定一个n个数的集合S和一个数x,求x在S的2n2n个子集从小到大的异或和序列中最早出现的位置 根据性质每一个数字出现的次数是相同的都是2^(n-cnt)个,cnt是线性基中元素得个数 #inc ...

  6. BZOJ2844 albus就是要第一个出场

    AC通道:http://www.lydsy.com/JudgeOnline/problem.php?id=2844 这题貌似HDU上有一道差不多的题,不过我没做过,也就没管了. 首先讲一个线性基的东西 ...

  7. [BZOJ2844]albus就是要第一个出场

    题目 传送门 to BZOJ 传送门 to VJ 思路 看到异或,想到线性基.再仔细观察一下,好像每个元素出现的次数都是一样的耶! 我们有两种证明方法.其一是,考虑某个异或和出现次数超过一的原因:⨁c ...

  8. BZOJ 2844 | HYSBZ - 2844albus就是要第一个出场——线性基

    [题目描述] BZOJ 2844 | HYSBZ - 2844albus [题目分析] 题目的意思大概是给一个数列,他有2n个子集,每个子集的元素的异或和构成新的一个数列,排序后问数字Q在这个序列里面 ...

  9. bzoj 2844: albus就是要第一个出场(线性基)

    2844: albus就是要第一个出场 Time Limit: 6 Sec  Memory Limit: 128 MB Submit: 1635  Solved: 680 [Submit][Statu ...

最新文章

  1. AI入门:不用任何公式把循环神经网络讲清楚
  2. CentOS 8下安装MySQL8.0
  3. linux 查看mysql运行时间_linux – strace显示从mysql socket读取很长时间 – mysql需要很长时间才能执行查询?...
  4. Kafka—简明教程
  5. 【华为云技术分享】【DevCloud· 敏捷智库】物理看板和电子看板该如何选择?(内附下载材料)
  6. React-Native 按钮点击几种效果进行对比
  7. [BUAA软工]团队贡献分博客
  8. QOS边界信任COS-交换机
  9. 重置密码解决MySQL for Linux错误 ERROR 1045 (28000):
  10. 闺女在大连上大学,一个月1500生活费她说少
  11. div中字符串自动换行
  12. 网络_简单实现远程唤醒与远程控制(Teamviewer)
  13. linux(ubuntu) 查看系统设备信息
  14. matlab时变函数,MATLAB在《复变函数》教学中的应用(图文)
  15. Quartus II中关于IP核的破解
  16. Ability、capability 和 capacity
  17. 出现“连接到服务器失败。错误: 0x80080005”错误的解决办法
  18. Nginx报upstream timed out错误
  19. 模型的偏差与方差的理解
  20. 【Java 8 新特性】Java 8 Collectors示例

热门文章

  1. 【Derivation】任何矩阵都相似与Jordan标准形证明
  2. 抖音运营变现必知的几个常识;新手不看后悔一辈子丨国仁网络资讯
  3. h6与php啥关系,哈佛m6跟哈佛h6的不同之处是什么发动机和底盘一样吗
  4. upload单独上传和统一上传
  5. csgo跳投指令_CSGO一键跳投脚本代码,附CFG文件下载
  6. C++11多线程第三篇:线程传参详解,detach()大坑,成员函数做线程参数
  7. 增长复盘|我们在小程序实现裂变!日拉新1000+
  8. Unity3D插件之EasyTouch5入门
  9. 用photoshop更换照片背景步骤
  10. 第一章 基础 (续 在IIS中寄宿服务)