zoukankan      html  css  js  c++  java
  • 2019.01.15-jzoj-子序列&&dtoj-4114-sub

    题目描述:

    他得到了一个长度为 n 的数组 a1,a2,a3,...,an,他想知道 xor 值为 0 的子 序列最长是多少。

    标签:线性基,FWT

    思路:

    我们要找异或值为0的,可以反过来寻找异或值为整个数组异或值的数。我们知道一个序列的线性基为权值位数,即至多为log个。

    所以我们可以知道异或值为总异或值的个数的至多有log次,次数不多。

    所以我们可以对整个序列做至多log次FWT,求出至少在第几次存在异或值等于总异或值,n-次数即为答案。

    以下代码:

    #include<bits/stdc++.h>
    #define il inline
    #define _(d) while(d(isdigit(ch=getchar())))
    using namespace std;
    const int N=6e5+5;
    int n,a[N],t=1,l,mx,sum,v[N],b[N],c[N];
    il int read(){int x;char ch;_(!);x=ch^48;_()x=(x<<1)+(x<<3)+(ch^48);return x;}
    il void fwt(int *s,int tp){
        for(int i=1;i<t;i<<=1){
            for(int j=0;j<t;j+=i<<1){
                for(int k=0;k<i;k++){
                    int A=s[j+k],B=s[i+j+k];
                    s[j+k]=A+B;s[i+j+k]=A-B;
                    if(tp==-1)s[j+k]=s[j+k]/2,s[i+j+k]=s[i+j+k]/2;
                }
            }
        }
    }
    int main()
    {
        n=read();for(int i=1;i<=n;i++){int x=read();b[x]=1;mx=max(mx,x);sum^=x;}
        while(t<=mx)t<<=1,l++;
        if(sum==0){printf("%d
    ",n);return 0;}
        if(b[sum]){printf("%d
    ",n-1);return 0;}
        fwt(b,1);for(int i=0;i<t;i++)c[i]=b[i];
        for(int k=1;;k++){
            if(k>1){
                for(int i=0;i<t;i++)if(c[i]!=0)c[i]=1;
                fwt(c,1);
            }
            for(int i=0;i<t;i++)c[i]=c[i]*b[i];
            fwt(c,-1);
            if(c[sum]!=0){printf("%d
    ",n-k-1);return 0;}
        }
        return 0;
    }
    View Code
  • 相关阅读:
    CentOS安装 Docker
    检测zookeeper和kafka是否正常
    开机自启动redis
    java学习笔记14--多线程编程基础1
    java学习笔记13--反射机制与动态代理
    JobControl 的实现原理
    Hadoop中Partition深度解析
    Mapper 与 Reducer 解析
    hadoop中OutputFormat 接口的设计与实现
    hadoop中InputFormat 接口的设计与实现
  • 原文地址:https://www.cnblogs.com/Jessie-/p/10274272.html
Copyright © 2011-2022 走看看