BZOJ2844:albus就是要第一个出场——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=2844
已知一个长度为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次出现时的下标是多少呢?
这话真的不是人说出来的。
简单翻译一下题就是序列所有的子集(可为空)的异或和经过排序,给一个q,求q在排序后序列中的位置下标。
参考:https://blog.sengxian.com/algorithms/linear-basis
如果是无重的,我们按照类似HDU3949:XOR的做法二进制分解q即可做(看代码应该更好理解吧)。
但是有重集合就很尴尬。
不过我们有对于一个数x,它出现次数一定是2^(n-size)(size为线性基大小)。
详细证明可以看参考,这里给出我的想法。
显然对于原线性基有且仅有一种方法构造出来x,且有且仅有一种方法构造出来非线性基内但却在a序列中的数。
那么对于非线性基内但却在a序列中的数有(n-size)个,它们和线性基内的数异或为0的方法有(n-size),排列组合就有2^(n-size)个,再与仅有一种方法构造出来x,就有2^(n-size)个了。
于是我知道了它去重前的排名,它排名前面的数都乘上2^(n-size)后+1即为答案。
PS:自己曾经也纠结过第一次算ans是否需要减一,但后来发现集合可为空……emmm这不值就有0了吗,对于0也满足这个性质啊,但是ans算排名的时候忽略了0啊。所以相当于ans-1+1=ans了啊。
#include<cstdio>
#include<iostream>
#include<vector>
#include<cstring>
#include<cmath>
#include<cctype>
#include<algorithm>
using namespace std;
const int N=;
const int p=;
const int BASE=;
inline int read(){
int X=,w=;char ch=;
while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
while(isdigit(ch))X=(X<<)+(X<<)+(ch^),ch=getchar();
return w?-X:X;
}
int qpow(int k,int n){
int res=;
while(n){
if(n&)res=res*k%p;
k=k*k%p;
n>>=;
}
return res;
}
int a[N],b[BASE+],cnt;
vector<int>mp;
int main(){
int n=read();
for(int i=;i<=n;i++){
a[i]=read();
for(int j=BASE;j>=;j--){
if(a[i]>>j&){
if(b[j])a[i]^=b[j];
else{
b[j]=a[i];cnt++;
break;
}
}
}
}
int q=read(),ans=;
for(int i=;i<=BASE;i++)
if(b[i])mp.push_back(i);
for(int i=;i<mp.size();i++){
if(q>>mp[i]&)ans+=<<i;
ans%=p;
}
ans=ans*qpow(,n-cnt)%p+;
printf("%d\n",ans%p);
return ;
}
+++++++++++++++++++++++++++++++++++++++++++
+本文作者:luyouqi233。 +
+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+
+++++++++++++++++++++++++++++++++++++++++++
BZOJ2844:albus就是要第一个出场——题解的更多相关文章
- BZOJ2844: albus就是要第一个出场
Description 已知一个长度为n的正整数序列A(下标从1开始), 令 S = { x | 1 <= x <= n }, S 的幂集2^S定义为S 所有子集构成的集合. 定义映射 f ...
- BZOJ2844: albus就是要第一个出场(线性基)
Time Limit: 6 Sec Memory Limit: 128 MBSubmit: 2054 Solved: 850[Submit][Status][Discuss] Descriptio ...
- 【贪心】【线性基】bzoj2844 albus就是要第一个出场
引用题解:http://blog.csdn.net/PoPoQQQ/article/details/39829237 注意评论区. #include<cstdio> using names ...
- bzoj千题计划195:bzoj2844: albus就是要第一个出场
http://www.lydsy.com/JudgeOnline/problem.php?id=2844 题意:给定 n个数,把它的所有子集(可以为空)的异或值从小到大排序得到序列 B,请问 Q 在 ...
- 【线性基】bzoj2844: albus就是要第一个出场
线性基求可重rank 题目描述 给定 n 个数 $\{ a_i \}$ ,以及数 $x$. 将 $\{ a_i \}$ 的所有子集(包括空集)的异或值从小到大排序,得到 $\{ b_i \} $. ...
- 【BZOJ2844】albus就是要第一个出场 高斯消元求线性基
[BZOJ2844]albus就是要第一个出场 Description 已知一个长度为n的正整数序列A(下标从1开始), 令 S = { x | 1 <= x <= n }, S 的幂集2 ...
- CF895C: Square Subsets && 【BZOJ2844】albus就是要第一个出场
CF895C: Square Subsets && [BZOJ2844]albus就是要第一个出场 这两道题很类似,都是线性基的计数问题,解题的核心思想也一样. CF895C Squa ...
- BZOJ 2844: albus就是要第一个出场 [高斯消元XOR 线性基]
2844: albus就是要第一个出场 题意:给定一个n个数的集合S和一个数x,求x在S的$2^n$个子集从小到大的异或和序列中最早出现的位置 一开始看错题了...人家要求的是x第一次出现位置不是第x ...
- BZOJ 2844: albus就是要第一个出场
2844: albus就是要第一个出场 Time Limit: 6 Sec Memory Limit: 128 MBSubmit: 1134 Solved: 481[Submit][Status] ...
随机推荐
- Chromium添加一段新字符串
参考:https://groups.google.com/a/chromium.org/forum/#!searchin/chromium-dev/tclib%7Csort:relevance/chr ...
- Linux命令应用大词典-第35章 终端
35.1 tty:显示当前连接到当前标准输入的终端设备文件名 35.2 consoletype:显示连接到标准输入的控制台类型 35.3 fgconsole:显示活动的虚拟终端数量 35.4 ming ...
- Python内嵌函数与Lambda表达式
//2018.10.29 内嵌函数与lambda 表达式 1.如果在内嵌函数中需要改变全局变量的时候需要用到global语句对于变 量进行一定的说明与定义 2.内部的嵌套函数不可以直接在外部进行访问 ...
- Eclipse上安装Activiti插件
今天我们来讲下如何在Eclipse上安装Activiti插件,以后我们要用这个插件来画流程设计图: 这个插件名字是:Activiti BPMN 2.0 designer 具体使用,可以参考官方用户指南 ...
- Django创建App报错
在django下创建APP项目时遇到的坑 python manage.py startapp app01 报错内容如下: 解决:找到报错中的文件夹151行删除items(),)中的逗号即可 在命令行下 ...
- halcon安装提示could not write updated path to HKLM
halcon安装提示could not write updated path to HKLM 我们在安装Halcon软件时,会弹出如上图错误信息,这个错误信息提示软件无法写入本地注册表,造成这个原因有 ...
- Kali渗透测试工具-netcat
netcat被称作是网络工具当中的瑞士军刀,短小却功能强大 1.端口扫描 nc -nvz 目标IP 端口范围 eg: nc -nvz 192.168.1.105 1-65535 -n参数是不要使用DN ...
- Microservices with Spring Boot
找到一套比较不错的Spring Boot/Cloud入门教程,推荐一下. https://dzone.com/users/1041459/ranga_pec.html
- 一道java笔试题
输入一串用空格隔开的数字串,对于数字串的奇数位按升序排序,偶数位按降序排序. 示例输入: 4 6 2 3 6 7 8 1 处理过程: 奇数位:4 2 6 8 升序排序结果: 2 4 6 8 偶数位:6 ...
- PCB各层介绍及AD软件画PCB时的规则
好久没画过板了,最近因为工作关系,硬件软件全部得自己来,不得不重新打开闲置很久的AltiumDesigner.以前做过点乱七八糟的笔记,本来想回头翻看一下,结果哪儿也找不到,估计已经被不小心删掉了. ...