zoukankan      html  css  js  c++  java
  • Educational Codeforces Round 12 E. Beautiful Subarrays 预处理+二叉树优化

    链接:http://codeforces.com/contest/665/problem/E

    题意:求规模为1e6数组中,连续子串xor值大于等于k值的子串数;

    思路:xor为和模2的性质,所以先预处理之后,可以枚举这种确实子串区间的方法为O(n^2);

    优化?把每一个前缀xor扔到二叉树中,从根节点出发,以高位前缀值的二进制数构造一颗二叉树,这样就可以在构造的时候,实现对子树节点个数的求解;之后在线求解到当前节点的可选的前缀xor的个数,

    即以k为主线

    如果当前位k为1,则在前缀二叉树中只能找和当前节点xor出结果为1的节点,并且这个节点的num值不能加到结果中;

    如果是当前位k为0,则直接加上xor结果为1的节点个数(num),方向不变;

    注:最后一个叶子节点不能求到,要在最后加上叶子节点的个数

    时间复杂度为O(nlgn)

     1 #include<iostream>
     2 #include<cstdio>
     3 using namespace std;
     4 const int MAXN = 11234567;
     5 int num[MAXN],tot = 1,d[MAXN][2],n,k;
     6 void update(int a)
     7 {
     8     for(int i = 30, p = 1;i >= 0;i--){
     9         if(d[p][(a>>i)&1] == 0) d[p][(a>>i)&1] = ++tot;
    10         p = d[p][(a>>i)&1];
    11         num[p]++;
    12     }
    13 }
    14 long long solve(int x)
    15 {
    16     long long  ans = 0, p = 1;
    17     for(int i = 30;i >= 0;i--){
    18         if((k>>i)&1) p = d[p][1^((x>>i)&1)];
    19         else{
    20             ans += num[d[p][1^((x>>i)&1)]];
    21             p = d[p][(x>>i)&1];
    22         }
    23     }
    24     return ans + num[p]; // leaf
    25 }
    26 int main()
    27 {
    28     cin>>n>>k;
    29     int prefix = 0,x;
    30     long long ans = 0;
    31     for(int i = 0;i < n;i++){
    32         update(prefix);
    33         scanf("%d",&x);
    34         prefix ^= x;
    35         ans += solve(prefix);
    36     }
    37     printf("%I64d",ans);
    38 }
  • 相关阅读:
    二次开发注意
    LAMP集群项目五 nfs分发文件到服务器
    LAMP集群项目五 nfs存储的数据实时同步到backupserver
    LAMP集群项目五 项目备份
    LAMP集群项目五 部署NFS存储服务并设置WEB服务挂载
    LAMP集群项目四 安装apache、php及其插件
    iOS-单选cell的实现
    iOS-省市区选择的实现
    随机颜色的产生
    刷新轮的使用
  • 原文地址:https://www.cnblogs.com/hxer/p/5563215.html
Copyright © 2011-2022 走看看