线性基

 

 

 

 

 

hdu3949XOR

求异或第k小

/*
    **author:revolIA
    *submit:
*/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxbit = 63;
ll bit[maxbit],Lbit[maxbit];
int main(){
    int t,Case = 0,n,m;
    scanf("%d",&t);
    while(t--){
        memset(bit,0,sizeof bit),m = 0;//初始化or清空
        printf("Case #%d:\n",++Case);
        scanf("%d",&n);
        for(int i=0;i<n;i++){
            ll x;
            scanf("%lld",&x);
            for(int j=maxbit-1;~j;j--)if((x>>j)&1){//插入
                if(!bit[j]){
                    bit[j] = x;
                    break;
                }
                x ^= bit[j];
            }
        }
        for(int i=maxbit-1;~i;i--){// 类似高斯消元
            for(int j=i+1;j<maxbit;j++){
                if((bit[j]>>i)&1)
                    bit[j] ^= bit[i];
            }
        }
        for(int i=0;i<maxbit;i++)if(bit[i])
            Lbit[m++] = bit[i];
        int q;
        scanf("%d",&q);
        while(q--){
            ll k;
            scanf("%lld",&k);
            if(n != m)// 0
                k--;
            if(k >= 1ll<<m){// 线性基最多表示多少个数
                printf("-1\n");
                continue;
            }
            ll ans = 0;
            for(int i=0;i<maxbit;i++)if((k>>i)&1)
                ans ^= Lbit[i];
            printf("%lld\n",ans);
        }
    }
    return 0;
}

 

Operation(2019杭电多校)

题意:

给一个长度n的数组,m次操作

操作:

0,询问[l,r]异或最大值

1,在数组最后添加一个数x

强制在线

所以,l,r,x,都要异或上一次的答案

l=(l\ xor\ ans)\%n+1

r=(r\ xor\ ans)\%n+1

​​​​​​​x=x\ xor\ ans

解:

处理一个 持久化的(前缀) 维护线性基内元素 当前位置向左第一次出现的位置(拗口、、)

 

如果不强制在线的话大概可以回滚莫队莽一下

 

/*
    **author:revolIA
    *submit:
*/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxbit = 31,maxn = 1e6+7;
int bit[maxn][maxbit],pos[maxn][maxbit];
void Add(int i,int x){
    int k = i;
    for(int j=maxbit-1;~j;j--)
        bit[i][j] = bit[i-1][j],pos[i][j] = pos[i-1][j];
    for(int j=maxbit-1;~j;j--)if((x>>j)&1){
        if(!bit[i][j]){
            bit[i][j] = x;
            pos[i][j] = k;
            break;
        }
        if(k>pos[i][j]){
            swap(k,pos[i][j]);
            swap(x,bit[i][j]);
        }
        x ^= bit[i][j];
    }
}
int main(){
    int t,n,q;
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&n,&q);
        for(int i=1,x;i<=n;i++)scanf("%d",&x),Add(i,x);
        int ans = 0;
        while(q--){
            int op,l,r;
            scanf("%d",&op);
            if(op){
                scanf("%d",&l);
                Add(++n,l^ans);
            }else{
                scanf("%d%d",&l,&r);
                l = (l^ans)%n+1,r = (r^ans)%n+1;
                if(l>r)swap(l,r);
                ans = 0;
                for(int j=maxbit-1;~j;j--)if(pos[r][j]>=l)
                    ans = max(ans,ans^bit[r][j]);
                printf("%d\n",ans);
            }
        }
        for(int i=1;i<=n;i++)for(int j=0;j<maxbit;j++)
            bit[i][j] = pos[i][j] = 0;
    }
    return 0;
}

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
线性可以用来判断原集合是否封闭。如果一个元素能够被线性向量线性表示,那么它就可以由原集合中的元素经过线性组合得到,即原集合是封闭的。否则,如果有一个元素不能被线性向量线性表示,那么它就无法由原集合中的元素经过线性组合得到,即原集合不是封闭的。 具体地,我们可以通过将待判断的元素与线性向量进行异或操作来判断是否能够线性表示。如果待判断元素与线性向量进行异或操作后得到零向量,则说明待判断元素可以由线性向量线性表示。如果待判断元素与线性向量进行异或操作后得到非零向量,则说明待判断元素无法由线性向量线性表示。 因此,我们可以通过判断待判断元素与线性向量进行异或操作的结果是否为零向量来判断原集合是否封闭。如果待判断元素与线性向量进行异或操作后都得到零向量,则原集合是封闭的;否则,原集合不是封闭的。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [线性模板](https://blog.csdn.net/weixin_43519854/article/details/96977900)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [【矩阵论】线性空间与线性变换(3)(4)](https://blog.csdn.net/kodoshinichi/article/details/108916238)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值