2844: albus就是要第一个出场

题目链接

题目大意:给定一个 n 个数的集合 S 和一个数 x ,求 x 在 S 的 2n 个子集从小到大的异或和序列中最早出现的位置

题解:考虑一个结论:对于一个n个数构成的大小为 k 的线性基
可以得到的 2k 个异或和每个会重复 2nk

从高到低枚举二进制位,异或这一位后小于 k 就加上

我的收获:2333

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <bitset>
using namespace std;
typedef long long ll;
const int N=1e5+5,INF=1e9,P=10086;
inline int read(){
    char c=getchar();int x=0,f=1;
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
int n,x;
int a[N],bin[70];
void ini(){
    bin[0]=1;for(int i=1;i<=30;i++) bin[i]=bin[i-1]<<1;
}    
int now;
void Gauss(){
    now=1;
    for(int i=30;i>=0;i--){
        int j=now;
        while(j<=n&&!(a[j]&bin[i])) j++;
        if(j==n+1) continue;
        if(j!=now) swap(a[j],a[now]);
        for(int k=1;k<=n;k++) 
            if(k!=now&&(a[k]&bin[i])) a[k]^=a[now];
        now++;
    }
    now--;
}
int main(){
    freopen("in","r",stdin);
    ini();
    n=read();
    for(int i=1;i<=n;i++) a[i]=read();
    Gauss();
    x=read();
    int val=0,sum=0;
    for(int i=1;i<=now;i++) if((val^a[i])<=x){
        val^=a[i];
        sum=(sum+(1<<(now-i))%P)%P;
    }
    for(int i=1;i<=n-now;i++) sum=(sum<<1)%P;
    printf("%d",(sum+1)%P);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值