线性基求可重rank

题目描述

给定 n 个数 $\{ a_i \}$ ,以及数 $x$。

将 $\{ a_i \}$​ 的所有子集(包括空集)的异或值从小到大排序,得到 $\{ b_i \} $。

求 $x$ 在 $\{ b_i \}$ 中第一次出现的下标。保证 $x$ 在 $\{ b_i \}$ 中出现。

HINT

数据范围:

1 <= N <= 10,0000

其他所有输入均不超过10^9


题目分析

考虑线性基求rank的过程,是一个求第k大的逆过程。也就是首先对线性基消元,再把线性基的元素给排出来,继而考虑每一位被线性基内第几个元素控制。

而现在是一个可重集,于是{1,1}和{1,1,1,1,1}就成了截然不同的两种情况。记线性基内有$legal$个元素,那么剩下就是$n-legal$个可被线性基表示的数字(下面简称无关数字)。沿用线性基题的一类思维方式,考虑这类无关数字对于线性基的影响。我们会发现,不论选出哪一部分无关数字(共$2^{n-legal}$种情况),都有且仅有一种“在线性基内选数”的方式使得选出的无关数字被重新异或为0.也就是说,记原rank为$preRank$,可重集rank就是$preRank*2^{n-legal}+1$。

对了,求原rank时候记得要和第k大操作一样把线性基元素重新拎出来。

 #include<bits/stdc++.h>
const int maxn = ;
const int MO = ; int n,p[],ans,legal; int read()
{
char ch = getchar();
int num = , fl = ;
for (; !isdigit(ch); ch = getchar())
if (ch=='-') fl = -;
for (; isdigit(ch); ch = getchar())
num = (num<<)+(num<<)+ch-;
return num*fl;
}
void insert(int x)
{
for (int i=, chk=; i>=&&!chk; i--)
if (x>>i){
if (p[i]) x ^= p[i];
else{
p[i] = x, chk = , ++legal;
for (int j=; j>i; j--)
if (p[j]>>i) p[j] ^= p[i];
}
}
}
void query(int x)
{
int i,j;
for (i=, j=; i<=; i++)
if (p[i]) p[j] = i, ++j;
for (i=j-; i>=; i--)
if ((<<p[i])&x) ans += (<<i);
}
int qmi(int a, int b)
{
int ret = ;
for (a%=MO; b; b>>=, a=a*a%MO)
if (b&) ret = ret*a%MO;
return ret;
}
int main()
{
n = read();
for (int i=; i<=n; i++) insert(read());
query(read());
ans = (1ll*ans*qmi(, n-legal)%MO+)%MO;
printf("%d\n",ans);
return ;
}

END

【线性基】bzoj2844: albus就是要第一个出场的更多相关文章

  1. 【贪心】【线性基】bzoj2844 albus就是要第一个出场

    引用题解:http://blog.csdn.net/PoPoQQQ/article/details/39829237 注意评论区. #include<cstdio> using names ...

  2. BZOJ2844: albus就是要第一个出场

    Description 已知一个长度为n的正整数序列A(下标从1开始), 令 S = { x | 1 <= x <= n }, S 的幂集2^S定义为S 所有子集构成的集合. 定义映射 f ...

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

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

  4. bzoj千题计划195:bzoj2844: albus就是要第一个出场

    http://www.lydsy.com/JudgeOnline/problem.php?id=2844 题意:给定 n个数,把它的所有子集(可以为空)的异或值从小到大排序得到序列 B,请问 Q 在  ...

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

    [BZOJ2844]albus就是要第一个出场 Description 已知一个长度为n的正整数序列A(下标从1开始), 令 S = { x | 1 <= x <= n }, S 的幂集2 ...

  6. BZOJ 2844: albus就是要第一个出场 [高斯消元XOR 线性基]

    2844: albus就是要第一个出场 题意:给定一个n个数的集合S和一个数x,求x在S的$2^n$个子集从小到大的异或和序列中最早出现的位置 一开始看错题了...人家要求的是x第一次出现位置不是第x ...

  7. BZOJ_2844 albus就是要第一个出场 【线性基】

    一.题目 albus就是要第一个出场 二.分析 非常有助于理解线性基的一题. 构造线性基$B$后,如果$|A| > |B|$,那么就意味着有些数可以由$B$中的数异或出来,而多的数可以取或者不取 ...

  8. CF895C: Square Subsets && 【BZOJ2844】albus就是要第一个出场

    CF895C: Square Subsets && [BZOJ2844]albus就是要第一个出场 这两道题很类似,都是线性基的计数问题,解题的核心思想也一样. CF895C Squa ...

  9. BZOJ 2844: albus就是要第一个出场

    2844: albus就是要第一个出场 Time Limit: 6 Sec  Memory Limit: 128 MBSubmit: 1134  Solved: 481[Submit][Status] ...

随机推荐

  1. nginx 第二课

    基本配置格式 Nginx全局配置参数 使用include文件 HTTP的server部分 虚拟服务器部分 location —— where,when,how. mail的server部分. 完整的示 ...

  2. C# 数组之int[]

    一.数组分类 数组可以简单分为3类: 1维数组 2维数组 交错数组 二.数组初始化 1.一维数组 int [] A = { 1,2,3,4 } 直接赋值 或者 int [] A = new int [ ...

  3. oracle 列转行

    with temp as( as S3 from dual union all as S3 from dual ) select * from temp unpivot(Qty for Sizes i ...

  4. jquery的$().each和$.each的区别

    在jquery中,遍历对象和数组,经常会用到$().each和$.each(),两个方法.两个方法是有区别的,从而这两个方法在针对不同的操作上,显示了各自的特点. $().each,对于这个方法,在d ...

  5. PHP的时间函数strtotime

    时间加减 [php] view plaincopy <?php //获取本地 提取年份+1 $date=date("Y-m-d",mktime(0,0,0,date(&quo ...

  6. 一道笔试题和UML思想 ~

    一句软件工程界的名言,让我想起了一个和一道笔试题有关的故事.希望更多的人了解 UML 背后的思想比他的语法更重要,是笔者写作本文的一点小愿望. 一.从一句软件工程名言说起 对很多事情的处理上,东西方都 ...

  7. C#基础文件file的各种套路

    File的各种套路 //创建一个文件 //File.Create(@"C:\Users\SpringRain\Desktop\new.txt"); //Console.WriteL ...

  8. 数据库(数据库、表及表数据、SQL语句)

    数据库MYSQL 今日内容介绍 u MySQL数据库 u SQL语句 第1章 数据库 1.1 数据库概述 l 什么是数据库 数据库就是存储数据的仓库,其本质是一个文件系统,数据按照特定的格式将数据存储 ...

  9. JSTORM中IRichBolt与IBasicBolt的区别

  10. Mysql中WHERE IN,UNION 用法详解

    WHERE IN 用法 这里分两种情况来介绍 1.in 后面是记录集,如: select  *  from  table  where   uname  in(select  uname  from  ...