bzoj2844

http://www.lydsy.com/JudgeOnline/problem.php?id=2844

线性基。。。

先把线性基搞出来,然后不断逼近答案,如果这个基比答案小了,那么说明要加上,同时加上贡献:现在的位i +1<<(now-i) 为什么呢,我是这样理解的:一个数分两种情况:选这位和不选这位,如果前面选的位和当前q不同的话,那么前面已经统计过答案了,每次统计答案都是当已经选的数是q的一个子集。我们统计的答案是不选这个位,不选的话,肯定q小,那么这样的数有1<<(now-i)个,因为后面有now-i个基。

然后还要+1,因为我们只统计了比这个数小的数的个数。还要乘上2^(n-now),因为前面now个数已经足够构成基底,那么后面n-now个数肯定会重复。这样会复制2^(n-now)个数。

还有一种解释方法:因为后面都被消成0了,所以选不选都没关系,又因为后面每个a的组合都不一样,和前面搭配都不一样,所以可以。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 100010, mod = 10086;
int n, now;
ll q;
ll a[N], bin[40];
void gauss()
{
    now = 1;
    for(int i = 30; i >= 0; --i)
    {
        int x = now;
        while(x <= n && !(a[x] & bin[i])) ++x; //没有这位
        if(x == n + 1) continue;
        swap(a[now], a[x]); // 消去这位其他的1
        for(int j = 1; j <= n; ++j) if(j != now && a[j] & bin[i]) a[j] ^= a[now];
        ++now;
    }
    --now;
}
int main()
{
    bin[0] = 1; for(int i = 1; i <= 30; ++i) bin[i] = bin[i - 1] * 2;
    scanf("%d", &n);
    for(int i = 1; i <= n; ++i) scanf("%d", &a[i]);
    scanf("%d", &q);
    gauss();
    ll ans = 0, val = 0;
    for(int i = 1; i <= now; ++i) if((val ^ a[i]) <= q)
    {
        val ^= a[i];
        ans += bin[now - i] % mod;
    }
    for(int i = 1; i <= n - now; ++i) ans = (ans << 1) % mod;
    ++ans;
    printf("%lld\n", (ans % mod + mod) % mod);
    return 0;
}

时间: 2024-10-28 12:38:04

bzoj2844的相关文章

【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就是要第一个出场 高斯消元求线性基

[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

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

#include <stdio.h> int main() { puts("转载请注明出处[vmurder]谢谢"); puts("网址:blog.csdn.net/vmurder/article/details/43456773"); } 题意:需要注意的是空集(0)是天生被包括的,我为了这个WA了好久~拍了好久,醉了好久~ 题解: 首先有一个我并不知道是为什么(甚至不知道它对不对)的性质: 每一种权值会出现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

关于高斯消元解决xor问题的总结

我觉得xor这东西特别神奇,最神奇的就是这个性质了 A xor B xor B=A 这样就根本不用在意重复之类的问题了 关于xor的问题大家可以去膜拜莫队的<高斯消元解XOR方程组>,里面写的很详细 我来扯两道bzoj上的例题好了 bzoj2115,求1-N最长xor路径,根据那个神奇的性质,我们先随便找一条1-n的路径作为标准路径 任意一条1-N的路径都等价于标准路径和某些环的xor 怎么找环?很简单,bfs下去,设d[x]表示1到x的一条路径xor值,如果到一条边x-->y时y已经访