• [BZOJ2844]线性基+xor本质不同第K大


    https://blog.csdn.net/qq_39759315/article/details/88789872?depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-4&utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-4

    https://blog.csdn.net/qq_39759315/article/details/88553043?depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-6&utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-6

    input
    4
    1
    2
    12
    13
    13
    output
    11


    拿这个样例来说,构成的线性基为(1,2,12)。13并没有进入其中,因为它与里面的数字xor出来后得到0了。
    当我们希望13排第几大的时候,我们要知道它是与哪些数字xor后得到0的。明显知道它是与12,1这两个数字xor变成0的。于是13在所有xor出来的数字中排第5大,这些值是各不相同的
    这个与我们上次做的hdu那个求第K大的xor结果,是逆运算。
    对于1,2,12三个数字
    12 2 1
    第1小 0 0 1
    第2小 0 1 0
    第3小 0 1 1
    第4小 1 0 0
    第5小 1 0 1
    第6小 1 1 0
    然后由于线性基只有3个元素,输入的数列中有4个。所以对于没加进去的13这样的元素
    如果我们将其加入到选出来的某个子集中,它都使算出来的结果等于另子集中的另一个元素
    也就是说所有算出来的结果,都将出现2次。
    于是5*2+1=11
    还有个空集哟

    对于样例

    2

    1

    12

    12

    输出结果为3.

    对于1,12三个数字
    12 1
    第1小 0 1
    第2小 1 0
    第3小 1 1
    对于询问的12,它是与12进行xor后的。于是排名第2小,加上0,就是第3小了。

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int MAXN=31;
    const int mod=10086;
    ll n,q,ans,cnt,now,a[50];
    void insert(ll v){
        for(int i=MAXN;i>=0;--i) if((v>>i)&1){
            if(a[i]) v^=a[i];
            else{
                for(int j=i-1;j>=0;--j)
                    if((v>>j)&1) v^=a[j];
                for(int j=i+1;j<=MAXN;++j)
                    if((a[j]>>i)&1) a[j]^=v;
                a[i]=v;
                break;
            }
        }
    }
    int main(){
        scanf("%lld",&n);ll x;
        for(int i=1;i<=n;++i){
            scanf("%lld",&x);insert(x);
        }
        for(int i=0;i<=MAXN;++i) if(a[i]) cnt++;
        scanf("%lld",&q);ll tmp=cnt;
        for(int i=MAXN;i>=0;--i)
    	{
            if(a[i])
    		{
                if((q>>i)&1)
    			{
                    ans+=pow(2,tmp-1);
                }
                tmp--;
            }
        }
        for(int i=1;i<=n-cnt;++i) ans=ans*2%mod;
        printf("%lld
    ",(ans+1)%mod);
        return 0;
    }
    
  • 相关阅读:
    什么是tomcat集群?
    cmd黑客入侵命令大全
    Linix基本命令
    Windows CMD命令大全
    python 函数1
    Python 集合(set)使用
    python 数据字典应用
    python 数据运算
    python 数据类型(元组(不可变列表),字符串
    python 数据类型(列表)学习笔记
  • 原文地址:https://www.cnblogs.com/cutemush/p/12770620.html
Copyright © 2020-2023  润新知