zoukankan      html  css  js  c++  java
  • [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;
    }
    
  • 相关阅读:
    PlateSpin 完全复制由于LVM没有可用空闲空间导致失败
    Linux LVM学习总结——放大LV容量
    Linux AVG ANTIVIRUS FREE使用介绍
    Linux如何查看JDK的安装路径
    Cannot set a credential for principal 'sa'. (Microsoft SQL Server,错误: 15535)
    记一次Linux服务器上查杀木马经历
    Linux NetHogs监控工具介绍
    Linux make: g++: Command not found
    Linux的NTP配置总结
    Linux内核的文件预读readahead
  • 原文地址:https://www.cnblogs.com/cutemush/p/12770620.html
Copyright © 2011-2022 走看看