牛客练习赛81 小Q与彼岸花 (分块+可持久化01trie)-程序员宅基地

技术标签: 01字典树  分块  

题意:
在这里插入图片描述
题解:因为这个题目是弱化以后的,正常的范围是5e4 .
看了官方题解去学习了一波可持久化01trie然后回来把这个题补完。

可持久数据结构其实就是我们的数据结构的内容会不断发生变化,而我们还要查询以前的历史版本,比如某个区间的情况。

听名字可以听出来,可持久化01trie跟可持久化线段树差不多的效果,对于01字典树来说,可以指定查询 l − r l-r lr 范围内的数组成的字典树。

但是针对于这个题目我们直接使用可持久化01trie进行维护,时间还是不能被允许的,所以说, 我们还需要去继续优化。

如何优化呢? 分块!
我们用数组 a n s [ x ] [ y ] ans[x][y] ans[x][y]预处理出来 块x到块y之间的区间任意两数的最大异或值。

时间复杂度呢?

我们把数组分成大小为 n \sqrt{n} n 的块,那么可以分成 ( n − 1 ) / n + 1 (n-1)/\sqrt{n}+1 (n1)/n +1个块
所以预处理的复杂度为:
O ( n ∗ n ∗ n ∗ l o g ( a m a x ) ) O(\sqrt{n}*\sqrt{n}*\sqrt{n}*log(a_{max}) ) O(n n n log(amax)) (类似于区间求解众数–强制在线)
应该没错。。。

for(int i=1;i<=sumblocks;i++){
    
    for(int j=i;j<=sumblocks;j++){
    
        int nowmax=ans[i][j-1];
        for(int k=(j-1)*sz+1;k<=min(n,j*sz);k++){
    
            int res=query(rt[min(j*sz,n)],a[k],(i-1)*sz+1);
            nowmax=max(nowmax,res);
        }
        ans[i][j]=nowmax;
    }
}

然后对于每次查询,如果l和r属于同一个块之间,那么我们直接暴力即可
那么如果不在同一个块呢,那么就跟最简单的分块一样了,先让最大值等于中间完整的块,然后我们暴力处理一下两边不全的块并不断更新最大值,然后返回最大值即可。

代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn=5e6+10;


int ans[300][300];
int a[maxn],buck[maxn];
int rt[maxn];
int sz,idx;
int trie[maxn*20][2];
int max_id[maxn];


void ins(int x,int pre,int now){
    for(int i=12;i>=0;i--){
        max_id[now]=x;
        int val=(a[x]>>i)&1;
        trie[now][val^1]=trie[pre][val^1];
        trie[now][val]=++idx;
        now=idx;
        pre=trie[pre][val];
    }
    max_id[now]=x;
}

int query(int root,int C,int L){
    int p=root;
    for(int i=12;i>=0;i--){
        int val=(C>>i)&1;
        if(max_id[trie[p][val^1]]>=L) p=trie[p][val^1];
        else p=trie[p][val];
    }
    return C^a[max_id[p]];
}

int get_block(int x){
    return (x-1)/sz+1;
}

int sol(int l,int r){
    int st=get_block(l);
    int ed=get_block(r);
    if(st==ed){
        int imax=0;
        for(int i=l;i<=r;i++){
            imax=max(imax,query(rt[r],a[i],l));
        }
        return imax;
    }
    else{
        int imax=ans[st+1][ed-1];
        //cout<<"debug   "<<imax<<endl;
        for(int i=l;i<=st*sz;i++){
            imax=max(imax,query(rt[r],a[i],l));
        }
        for(int i=(ed-1)*sz+1;i<=r;i++){
            imax=max(imax,query(rt[r],a[i],l));
        }
        return imax;
    }
}


int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n,m;
    cin>>n>>m;
    sz=sqrt(n);
    for(int i=1;i<=n;i++){
        cin>>a[i];
        rt[i]=++idx;
        ins(i,rt[i-1],rt[i]);
    }
    int sumblocks=(n-1)/sz+1;

    for(int i=1;i<=sumblocks;i++){
        for(int j=i;j<=sumblocks;j++){
            int nowmax=ans[i][j-1];
            for(int k=(j-1)*sz+1;k<=min(n,j*sz);k++){
                int res=query(rt[min(j*sz,n)],a[k],(i-1)*sz+1);
                nowmax=max(nowmax,res);
            }
            ans[i][j]=nowmax;
        }
    }

    while(m--){
        int l,r;
        cin>>l>>r;
        int xxx=sol(l,r);
        cout<<xxx<<endl;
    }
    return 0;

}

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/xxxxxiao123/article/details/116167178

智能推荐

Android生态系统进化论_即妇人遇之,亦有为其所污者的翻译-程序员宅基地

文章浏览阅读3.6k次。近几年,在美国有一派作先驱研究的生物家认为,目前整个自然界生态系统中,物种之间是有隔绝的。马不可能和熊,鱼不可能和企鹅,就连人都不可能和近亲猩猩生出宝宝。虽然组成我们这颗行星上的自然生态物种,其DNA都是四种最为基本的物质——ACGT。但是不同物种之间,是无法通过交换基因的机制,衍生出一种崭新的生命和物种的。我们这个自然界中,不同的物种之间的基因交换是被隔绝的。生物科学的生态系统,究竟与我们今天的_即妇人遇之,亦有为其所污者的翻译

230. 二叉搜索树中第K小的元素(BST)_编写一个程序要求返回在bst中第k小的元素。-程序员宅基地

文章浏览阅读248次。230. 二叉搜索树中第K小的元素题目解题思路代码题目给定一个二叉搜索树,编写一个函数 kthSmallest 来查找其中第 k 个最小的元素。说明:你可以假设 k 总是有效的,1 ≤ k ≤ 二叉搜索树元素个数。进阶:如果二叉搜索树经常被修改(插入/删除操作)并且你需要频繁地查找第 k 小的值,你将如何优化 kthSmallest 函数?解题思路、这题可以考虑到用中序遍历,把中序遍历的结果依次存放在 list中,这样第1小的就是存放在list中的下标为0的位置,所以求第k小的,只要去li_编写一个程序要求返回在bst中第k小的元素。

Log4j漏洞修复_log4j 2.11.2漏洞修复方案-程序员宅基地

文章浏览阅读6.3k次,点赞10次,收藏38次。原因: log4j被爆安全漏洞,紧急进行版本修复。过程: 项目中查找是否使用到log4j,发现在lombok中有使用log4j 2.11.2版本解决方案:在pom文件中找到lombok节点 添加排除属性<exclusions>因在maven仓库中没有log4j-2.15.0-rc2.jar 。[jar下载地址](https://archiva-maven-storage-prod.oss-cn-beijing.aliyuncs.com/repository/central/#_log4j 2.11.2漏洞修复方案

51单片机 IIC OLED驱动显示通用程序模板_51单片机oled显示程序-程序员宅基地

文章浏览阅读5.6k次,点赞16次,收藏176次。0.96寸OLED IIC驱动显示通用模板程序代码_51单片机oled显示程序

input[type="file"]的样式以及文件名的显示-程序员宅基地

文章浏览阅读501次。如何美化input[type="file"]基本思路是:(1)首先在 input 外层套一个 div ;(2)将 div 和 input 设置为一样大小(width和height);(3)设置 div 为相对位置, input 为绝对位置,并将 input 的 top 和 right 设为 0 ;这样, div 和 input 就重叠了,点击 div 就相当于点击 input ..._type="file"怎么显示名字

iBarn基于PHP MYSQL开源网盘 - 堪比百度网盘-程序员宅基地

文章浏览阅读3.6k次。iBarn是一个基于PHP的先进的网盘系统,提供文件的网络备份,同步和分享服务。支持断点续传,秒传等功能。可选择文件下载到本地或者在线收藏;回收站功能防止用户误删数据;云存储的不二之选。_ibarn

随便推点

ffmpeg+SDL-程序员宅基地

文章浏览阅读832次,点赞23次,收藏16次。学习雷博士的文章16.04.7ffmpeg-6.1。

windows和Linux下Fortran编译环境的配置_fortran程序及部署linux-程序员宅基地

文章浏览阅读8.8k次,点赞14次,收藏47次。Fortran是最早出现的高级程序设计语言之一,主要适合用来解决科学计算方面的问题,主要优点是计算效率很高。要想学习一门语言,首先是学习工具,在书籍方面推荐大家参考《Fortran程序设计》(第四版),接下来主要为大家介绍如何在windows和linux下配置Fortran的编译环境。windows下Fortran编译环境的配置在windows下推荐大家配合使用Visual Studio(VS) + Intel Visual Fortran(IVF),关于这两个软件的下载与安装,大家可以参考这篇博文:_fortran程序及部署linux

机器学习与深度学习中的数学知识点汇总-程序员宅基地

文章浏览阅读928次。点击上方“小白学视觉”,选择加"星标"或“置顶”重磅干货,第一时间送达本文转自|AI算法与图像处理在机器学习与深度学习中需要大量使用数学知识,这是给很多初学带来困难的主..._机器视觉与深度学习涉及的高数知识

如何在ES6中判断类中是否包含某个属性和方法_es6判断对象包含某个属性-程序员宅基地

文章浏览阅读7.5k次。1、应用方法 hasOwnProperty2、应用实例class Student{ constructor(sno,sname,sage,ssex) { this.sno = sno; this.sname = sname; this.sage = sage; this.ssex = ssex; } toString(){..._es6判断对象包含某个属性

尝试手写一个框架(二)手写一个MVC的框架_手写mvc框架-程序员宅基地

文章浏览阅读8.1k次,点赞7次,收藏6次。通过使用servlet,结合注解标记,实现一个简单的实现一个MVC框架_手写mvc框架

Android SVG动画详细例子-程序员宅基地

文章浏览阅读1.7k次,点赞16次,收藏8次。在之前发了一篇关于SVG动画的文章,有小伙伴反应了一些问题,所以出一篇较为详细的动画例子文章,希望有所帮助。_android svg动画

推荐文章

热门文章

相关标签