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

2844: albus就是要第一个出场

Time Limit: 6 Sec  Memory Limit: 128 MB
Submit: 1134  Solved: 481
[Submit][Status][Discuss]

Description

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

集构成的集合。定义映射 f : 2^S -> Zf(空集) = 0f(T) = XOR A[t] , 对于一切t属于T现在albus把2^S中每个集

合的f值计算出来, 从小到大排成一行, 记为序列B(下标从1开始)。 给定一个数, 那么这个数在序列B中第1

次出现时的下标是多少呢?

Input

第一行一个数n, 为序列A的长度。接下来一行n个数, 为序列A, 用空格隔开。最后一个数Q, 为给定的数.

Output

共一行, 一个整数, 为Q在序列B中第一次出现时的下标模10086的值.

Sample Input

3
1 2 3
1

Sample Output

3
样例解释:
N = 3, A = [1 2 3]
S = {1, 2, 3}
2^S = {空, {1}, {2}, {3}, {1, 2}, {1, 3}, {2, 3}, {1, 2, 3}}
f(空) = 0
f({1}) = 1
f({2}) = 2
f({3}) = 3
f({1, 2}) = 1 xor 2 = 3
f({1, 3}) = 1 xor 3 = 2
f({2, 3}) = 2 xor 3 = 1
f({1, 2, 3}) = 0
所以
B = [0, 0, 1, 1, 2, 2, 3, 3]

HINT

数据范围:

1 <= N <= 10,0000

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

Source

湖北省队互测

[Submit][Status][Discuss]

线性基裸题

 1 #include <cstdio>
 2
 3 __inline void swap(int &a, int &b)
 4 {
 5     a^= b ^= a ^= b;
 6 }
 7
 8 const int mod = 10086;
 9 const int mxn = 100005;
10
11 int n, m, a[mxn], b[mxn], c, ans = 1;
12
13 inline int pow(int a, int b)
14 {
15     int ret = 1;
16
17     for (; b; b >>= 1, (a *= a) %= mod)
18         if (b & 1)(ret *= a) %= mod;
19
20     return ret;
21 }
22
23 inline void gauss(void)
24 {
25     for (int i = 1; i <= n; ++i)
26     {
27         for (int j = i + 1; j <= n; ++j)
28             if (a[i] < a[j])swap(a[i], a[j]);
29
30         if (a[i])
31             ++c;
32         else
33             break;
34
35         for (int j = 31; j >= 0; --j)
36             if ((a[i] >> j) & 1)
37             {
38                 b[i] = j;
39
40                 for (int k = 1; k <= n; ++k)
41                     if (k != i && (a[k] >> j) & 1)
42                         a[k] ^= a[i];
43
44                 break;
45             }
46     }
47 }
48
49 signed main(void)
50 {
51     scanf("%d", &n);
52
53     for (int i = 1; i <= n; ++i)
54         scanf("%d", a + i);
55
56     gauss();
57
58     scanf("%d", &m);
59
60     for (int i = 1; i <= c; ++i)
61         if ((m >> b[i]) & 1)m ^= a[i],
62             (ans += pow(2, n - i)) %= mod;
63
64     printf("%d\n", ans);
65 }

@Author: YouSiki

时间: 2024-10-09 08:30:00

BZOJ 2844: albus就是要第一个出场的相关文章

BZOJ 2844 albus就是要第一个出场 ——高斯消元 线性基

[题目分析] 高斯消元求线性基. 题目本身不难,但是两种维护线性基的方法引起了我的思考. 1 2 3 4 5 6 7 8 9 10 11 12 void gauss(){     k=n;     F(i,1,n){         F(j,i+1,n) if (a[j]>a[i]) swap(a[i],a[j]);         if (!a[i]) {k=i-1; break;}         D(j,30,0) if (a[i]>>j & 1){            

BZOJ 2844 albus就是要第一个出场 高斯消元

题目大意:给定一个n个数的集合S和一个数x,求x在S的2^n个子集从大到小的异或和序列中最早出现的位置 有学长真好不用自己打题目大意了233 首先我们求出线性基 我们会得到一些从大到小排列的数和一堆0 记录0的个数 不考虑0,看前面的数,由于线性基的性质,我们直接贪心从大到小枚举 若当前异或和异或这个值小于Q则取这个数 (注意^不要写成+或者| 本蒟蒻已经因为这个WA了两道题了 然后我们通过每个数取不取可以得到一个01序列 这个序列就是通过异或可以得到的小于Q的数的数量的二进制 比如线性基是8

BZOJ 2844 albus就是要第一个出场 高斯消元+线性基

题目大意:给出一个长度为n的正整数数列A.每次选出A的一个子集进行抑或(空集抑或值为0),这样就得到一个长度为2^n的数列B.将B中元素升序排序.给出一个数字m,求m的B中出现的最小位置. 思路:线性基的性质:假设n个数可以消出k个线性基,那么显然会有2^k个不同的亦或和,n个数相互排列显然会有2^n个.神奇的事情就在于每种亦或和居然是一样多的,也就是都是2^(n - k)个.有了这个解决这个题就简单了,做一下高斯消元来求出线性基.正常的求法不行,因为要保证消元的时候一个位置上只能有一个1. C

bzoj 2844: albus就是要第一个出场 线性基

首先线性基是什么呢.我们考虑我们有n个数.子集数量为2^n个.我们将每个子集内的数全部异或起来.得到一个值.但是我们考虑这些值内会可能存在重复的,太多了.不便于运算.所以我们考虑,能不能除去重复的. 我们假定n个数都是<10^9.我们考虑使用一个30*30的矩阵.其中其中第一行,存一个最高位1位于数字第1位的数.第二行存一个最高位1位于数字2位的数.以此类推.这样子我们可以得到一个30*30的的矩阵.这个矩阵未必每一行都填满.我们可以考虑,加入一个元素,发现他对应的行已经被填满了.我们将这个数和

【BZOJ 2844】 albus就是要第一个出场

2844: albus就是要第一个出场 Time Limit: 6 Sec  Memory Limit: 128 MB Submit: 436  Solved: 190 [Submit][Status] Description 已知一个长度为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 现

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

[BZOJ2844]albus就是要第一个出场 Description 已知一个长度为n的正整数序列A(下标从1开始), 令 S = { x | 1 <= x <= n }, S 的幂集2^S定义为S 所有子集构成的集合.定义映射 f : 2^S -> Zf(空集) = 0f(T) = XOR A[t] , 对于一切t属于T现在albus把2^S中每个集合的f值计算出来, 从小到大排成一行, 记为序列B(下标从1开始). 给定一个数, 那么这个数在序列B中第1次出现时的下标是多少呢? I

【BZOJ】【2844】albus就是要第一个出场

高斯消元解XOR方程组 srO  ZYF  Orz 膜拜ZYF…… http://www.cnblogs.com/zyfzyf/p/4232100.html 1 /************************************************************** 2 Problem: 2844 3 User: Tunix 4 Language: C++ 5 Result: Accepted 6 Time:252 ms 7 Memory:2052 kb 8 *******

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

http://www.lydsy.com/JudgeOnline/problem.php?id=2844 (题目链接) 题意 给出${n}$个数,它们可以异或出${n^2}$个数,将这些数从小到大排列起来,问${Q}$最早出现的位置. Solution 原来线性基还有这种性质,我怎么不知道→_→ 假设${n}$个数可以消出${k}$个线性基,那么显然会有${2^k}$个不同的亦或和,${n}$个数相互排列显然会有${2^n}$个.神奇的事情就在于每种亦或和居然是一样多的,也就是都是${2^{n

bzoj2844 albus就是要第一个出场

题意:http://www.lydsy.com/JudgeOnline/problem.php?id=2844 sol  :因为这个是不去重空间,所以麻烦点QAQ 考虑去重空间的做法,直接线性基+树形dp即可 而对于不去重空间,其大小为2^n,求出异或空间的秩m,则去重空间的大小为2^m 那么去重异或空间的每个值在不去重异或空间里出现2^(n-m)次 所以答案即为去重异或空间的答案*2(n-m)+1即可 记得开long long #include<iostream> #include<a