bzoj2844 albus就是要第一个出场(线性基【询问排名)
题目链接
分析:
这道题是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就是要第一个出场(线性基【询问排名)相关推荐
- BZOJ2844: albus就是要第一个出场(线性基)
Time Limit: 6 Sec Memory Limit: 128 MB Submit: 2054 Solved: 850 [Submit][Status][Discuss] Descript ...
- 【BZOJ2844】albus就是要第一个出场——线性基
Time Limit: 6 Sec Memory Limit: 128 MB Description 已知一个长度为n的正整数序列A(下标从1开始), 令 S = { x | 1 <= x &l ...
- 【BZOJ2844】albus就是要第一个出场 线性基 高斯消元
#include <stdio.h> int main() {puts("转载请注明出处[vmurder]谢谢");puts("网址:blog.csdn.ne ...
- [BZOJ2844]albus就是要第一个出场(线性基)
题目: 我是超链接 题解: 先不考虑重复数字的问题,如果要求数字Q的出现位置的话,首先一个比较直观的想法是,如果能求出这样一组基底,它从小到大排序以后可以满足:设只选i向量构造出来的数字为R,那么1. ...
- 【bzoj2844 albus就是要第一个出场】
题意:给定一个n个数的集合S和一个数x,求x在S的2n2n个子集从小到大的异或和序列中最早出现的位置 根据性质每一个数字出现的次数是相同的都是2^(n-cnt)个,cnt是线性基中元素得个数 #inc ...
- BZOJ2844 albus就是要第一个出场
AC通道:http://www.lydsy.com/JudgeOnline/problem.php?id=2844 这题貌似HDU上有一道差不多的题,不过我没做过,也就没管了. 首先讲一个线性基的东西 ...
- [BZOJ2844]albus就是要第一个出场
题目 传送门 to BZOJ 传送门 to VJ 思路 看到异或,想到线性基.再仔细观察一下,好像每个元素出现的次数都是一样的耶! 我们有两种证明方法.其一是,考虑某个异或和出现次数超过一的原因:⨁c ...
- BZOJ 2844 | HYSBZ - 2844albus就是要第一个出场——线性基
[题目描述] BZOJ 2844 | HYSBZ - 2844albus [题目分析] 题目的意思大概是给一个数列,他有2n个子集,每个子集的元素的异或和构成新的一个数列,排序后问数字Q在这个序列里面 ...
- bzoj 2844: albus就是要第一个出场(线性基)
2844: albus就是要第一个出场 Time Limit: 6 Sec Memory Limit: 128 MB Submit: 1635 Solved: 680 [Submit][Statu ...
最新文章
- AI入门:不用任何公式把循环神经网络讲清楚
- CentOS 8下安装MySQL8.0
- linux 查看mysql运行时间_linux – strace显示从mysql socket读取很长时间 – mysql需要很长时间才能执行查询?...
- Kafka—简明教程
- 【华为云技术分享】【DevCloud· 敏捷智库】物理看板和电子看板该如何选择?(内附下载材料)
- React-Native 按钮点击几种效果进行对比
- [BUAA软工]团队贡献分博客
- QOS边界信任COS-交换机
- 重置密码解决MySQL for Linux错误 ERROR 1045 (28000):
- 闺女在大连上大学,一个月1500生活费她说少
- div中字符串自动换行
- 网络_简单实现远程唤醒与远程控制(Teamviewer)
- linux(ubuntu) 查看系统设备信息
- matlab时变函数,MATLAB在《复变函数》教学中的应用(图文)
- Quartus II中关于IP核的破解
- Ability、capability 和 capacity
- 出现“连接到服务器失败。错误: 0x80080005”错误的解决办法
- Nginx报upstream timed out错误
- 模型的偏差与方差的理解
- 【Java 8 新特性】Java 8 Collectors示例
热门文章
- 【Derivation】任何矩阵都相似与Jordan标准形证明
- 抖音运营变现必知的几个常识;新手不看后悔一辈子丨国仁网络资讯
- h6与php啥关系,哈佛m6跟哈佛h6的不同之处是什么发动机和底盘一样吗
- upload单独上传和统一上传
- csgo跳投指令_CSGO一键跳投脚本代码,附CFG文件下载
- C++11多线程第三篇:线程传参详解,detach()大坑,成员函数做线程参数
- 增长复盘|我们在小程序实现裂变!日拉新1000+
- Unity3D插件之EasyTouch5入门
- 用photoshop更换照片背景步骤
- 第一章 基础 (续 在IIS中寄宿服务)