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
  • 相关阅读:
    UnicodeDecodeError: 'utf-8' codec can't decode byte 0xef in position 99: invalid continuation byte
    Java的内存机制
    sort
    ajax()函数传值中文乱码解决方法介绍
    三种实现Ajax的方式
    找到div下的第一个ul
    POI 单元格
    js对字符串进行编码方法总结
    相对路径和绝对路径的区别,java获取项目访问路径的方法
    sql存储过程几个简单例子
  • 原文地址:https://www.cnblogs.com/Jessie-/p/10274272.html
Copyright © 2011-2022 走看看