• 51nod 1577 异或凑数(线性基)


    分析:如果能知道区间线性基,问题就解决了,所以一开始有个naive的想法,搞个线性基线段树,然而复杂度(32*nlogn),果断T。。。

    正解是预处理后缀线性基,并且每个基中的每一个分量位置尽量靠前,然后把k丢到左端点对应的线性基里跑,如果k最后不为0或者需要异或的位置超过了r,答案就是NO。

    这样的后缀线性基可以从后面开始处理,插入x时,如果某一位已经有数且在数组中的位置在x之后,把x放入线性基替换掉这个数,然后用这个数接着跑。

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #define SWAP(x, y)x ^= y, y ^=x, x ^= y;
     5 using namespace std;
     6 const int maxn = 5e5 + 5, inf = 1e9;
     7 int n;
     8 struct LinearBase{
     9     int a[32], n, loca[32];
    10     LinearBase(){
    11         memset(a, 0, sizeof(a));
    12         memset(loca, 0, sizeof(loca));
    13         n = 0;
    14     }
    15     void insert(int x, int k){
    16         int cur_loca = k;
    17         int d = 31;
    18         while(x && d >= 0){
    19             if(x & (1 << d)){
    20                 if(a[d]){
    21                     if(cur_loca < loca[d]){
    22                         SWAP(loca[d], cur_loca);
    23                         SWAP(a[d], x);
    24                     }
    25                     x ^= a[d];
    26                 }else{
    27                     loca[d] = cur_loca;
    28                     a[d] = x;
    29                     n++;
    30                     break;
    31                 }
    32             }
    33             d--;
    34         }
    35     }
    36     LinearBase operator = (LinearBase x){
    37         x.n = n;
    38         for(int i = 0; i < 32; i++)a[i] = x.a[i], loca[i] = x.loca[i];
    39     }
    40     int check(int k){
    41         int d = 31, r_min = 0;
    42         while(k && d>=0){
    43             if(k & (1 << d)){
    44                 if(!a[d])return inf;
    45                 r_min = max(r_min, loca[d]);
    46                 k ^= a[d];
    47             }
    48             d--;
    49         }
    50         if(k)return inf;
    51         return r_min;
    52     }
    53 }lb[maxn];
    54 int read(){
    55     int ans = 0;
    56     char last = ' ', ch = getchar();
    57     while(ch >= '0' && ch <= '9')ans = ans * 10 + ch - '0', ch = getchar();
    58     return ans;
    59 }
    60 bool check(int l, int r, int k){
    61     LinearBase &b = lb[l];
    62     if(b.check(k) <= r)return true;
    63     return false;
    64 }
    65 int a[maxn];
    66 int main(){
    67 //    freopen("e:\in.txt","r",stdin);
    68     n = read();
    69     for(int i = 1; i <= n; i++)a[i] = read();
    70     lb[n].insert(a[n], n);
    71     for(int i = n - 1; i >= 0; i--){
    72         lb[i] = lb[i + 1];
    73         lb[i].insert(a[i], i);
    74     }
    75     int m,l,r,k;
    76     m = read();
    77     for(int i = 0; i < m; i++){
    78         l = read();r = read();k = read();
    79         if(check(l, r, k))puts("YES");
    80         else puts("NO");
    81     }
    82     return 0;
    83 }
  • 相关阅读:
    注解-案例
    注解(Annotation)
    适合新手看的超详细CentOS Linux 7 安装Tomcat8过程
    CentOS Linux 7 提示 lsof: 未找到命令
    解决MySql报错:1130
    Spring Boot 创建自定义的properties文件
    spring boot 使用Schedule创建轻量级定时任务
    4.Java数组模块
    3.IDEA开发工具
    2.java基础语法
  • 原文地址:https://www.cnblogs.com/7391-KID/p/7816642.html
Copyright © 2020-2023  润新知