正题

题目链接:https://www.luogu.com.cn/problem/P3793


题目大意

给出\(n\)个数字的一个序列\(m\)次询问区间最大值

保证数据随机

\(1\leq n,m\leq 2\times 10^7\)


解题思路

使用\(ST\)表可以做到\(O(1)\)询问,但是预处理的时空复杂度都是\(O(n\log n)\),且自带大常数导致过不了。

如何加快预处理的时间,(因为是lxl的题目所以)考虑使用分块。每次询问可以分为整块的部分和不是整块的零散部分。

去掉没有跨块的情况,那么零散的部分就是块内前后缀最大值。然后整块的部分用\(ST\)表就好了。

那么没有跨块的情况是不是还需要给每个块维护一个\(ST\)表?这样空间还是过不了,其实可以考虑将没有跨块的情况按顺序每个块每个块离线处理,这样就可以过了。

但是数据保证随机,所以随机到同一个块内的概率是\(\frac{1}{T}\),也就是期望\(\sqrt n\)次,暴力处理是\(O(\sqrt n)\)的,所以直接暴力处理就可以了

时间复杂度\(O(n\log\sqrt n+m)\)。


code

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int N=2e7+10;
namespace GenHelper{
unsigned z1,z2,z3,z4,b;
unsigned rand_()
{
b=((z1<<6)^z1)>>13;
z1=((z1&4294967294U)<<18)^b;
b=((z2<<2)^z2)>>27;
z2=((z2&4294967288U)<<2)^b;
b=((z3<<13)^z3)>>21;
z3=((z3&4294967280U)<<7)^b;
b=((z4<<3)^z4)>>12;
z4=((z4&4294967168U)<<13)^b;
return (z1^z2^z3^z4);
}
}
void srand(unsigned x)
{using namespace GenHelper;
z1=x; z2=(~x)^0x233333333U; z3=x^0x1234598766U; z4=(~x)+51;}
int read()
{
using namespace GenHelper;
int a=rand_()&32767;
int b=rand_()&32767;
return a*32768+b;
}
int n,m,a[N],lg[N],p[N],q[N],g[5000][13];
int L[5000],R[5000],pos[N];
unsigned s;
unsigned long long ans;
int AskT(int l,int r){
if(l>r)return 0;int z=lg[r-l+1];
return max(g[l][z],g[r-(1<<z)+1][z]);
}
int main()
{
scanf("%d%d%u",&n,&m,&s);
srand(s);
for(int i=1;i<=n;i++)a[i]=read();
int T=sqrt(n);
for(int i=1;i<=T;i++)
L[i]=R[i-1]+1,R[i]=i*T;
if(R[T]!=n)++T,L[T]=R[T-1]+1,R[T]=n;
for(int i=1;i<=T;i++){
for(int j=L[i];j<=R[i];j++)pos[j]=i,g[i][0]=max(g[i][0],a[j]);
p[L[i]]=a[L[i]];q[R[i]]=a[R[i]];
for(int j=L[i]+1;j<=R[i];j++)p[j]=max(p[j-1],a[j]);
for(int j=R[i]-1;j>=L[i];j--)q[j]=max(q[j+1],a[j]);
}
for(int j=1;(1<<j)<=T;j++)
for(int i=1;i+(1<<j)-1<=T;i++)
g[i][j]=max(g[i][j-1],g[i+(1<<j-1)][j-1]);
for(int i=2;i<=T;i++)lg[i]=lg[i>>1]+1;
for(int i=1;i<=m;i++){
int l=read(),r=read();
l=l%n+1;r=r%n+1;
if(l>r)swap(l,r);
int x=pos[l],y=pos[r];
int tmp=0;
if(x==y){
for(int i=l;i<=r;i++)
tmp=max(tmp,a[i]);
}
else{
tmp=AskT(x+1,y-1);
tmp=max(tmp,max(q[l],p[r]));
}
ans+=tmp;
}
printf("%llu\n",ans);
}

P3793-由乃救爷爷【分块,ST表】的更多相关文章

  1. Luogu3793 由乃救爷爷 分块、ST表

    传送门 因为昨天写暴力写挂在UOJ上用快排惨遭卡常,所以今天准备写一个卡常题消遣消遣,然后时间又垫底了QAQ 这道题显然需要支持一个\(O(N)\)预处理\(O(1)\)查询的ST表,显然普通的ST表 ...

  2. [洛谷P3793]由乃救爷爷

    题目大意:有$n(n\leqslant2\times10^7)$个数,$m(m\leqslant2\times10^7)$个询问,每次询问问区间$[l,r]$中的最大值.保证数据随机 题解:分块,处理 ...

  3. 【JZOJ5064】【GDOI2017第二轮模拟day2】友好城市 Kosarajo算法+bitset+ST表+分块

    题面 在Byteland 一共有n 座城市,编号依次为1 到n,这些城市之间通过m 条单向公路连接. 对于两座不同的城市a 和b,如果a 能通过这些单向道路直接或间接到达b,且b 也能如此到达a,那么 ...

  4. Luogu 3793 由乃救爷爷

    \(\verb|Luogu 3793 由乃救爷爷|\) rmq,数据随机 \(n,\ m\leq 2\times10^7\) lxl ST表 分块,大小设为 \(x\) 预处理每个块两端到块内每个点的 ...

  5. [bzoj4540][Hnoi2016][序列] (莫队算法+单调栈+st表)

    Description 给定长度为n的序列:a1,a2,…,an,记为a[1:n].类似地,a[l:r](1≤l≤r≤N)是指序列:al,al+1,…,ar-1,ar.若1≤l≤s≤t≤r≤n,则称a ...

  6. [BZOJ1012] [JSOI2008] 最大数maxnumber (ST表)

    Description 现在请求你维护一个数列,要求提供以下两种操作:1. 查询操作.语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值.限制:L不超过当前数列的长度.2. 插 ...

  7. CF1039E Summer Oenothera Exhibition 贪心、根号分治、倍增、ST表

    传送门 感谢这一篇博客的指导(Orzwxh) $PS$:默认数组下标为$1$到$N$ 首先很明显的贪心:每一次都选择尽可能长的区间 不妨设$d_i$表示在取当前$K$的情况下,左端点为$i$的所有满足 ...

  8. CF1039E Summer Oenothera Exhibition 根号分治,LCT,ST表

    CF1039E Summer Oenothera Exhibition LG传送门 根号分治好题. 可以先看我的根号分治总结. 题意就是给出长度为\(n\)的区间和\(q\)组询问以及一个\(w\), ...

  9. 【笔记】自学ST表笔记

    自学ST表笔记 说实话原先QBXT学的ST表忘的差不多了吧...... 我重新自学巩固一下(回忆一下) 顺便把原先一些思想来源的原博发上来 一.ST表简介 ST表,建表时间\(O(n\cdot log ...

随机推荐

  1. WPF 中的 Command 命令

    <Window x:Class="CommandDemo.MainWindow" xmlns="http://schemas.microsoft.com/winfx ...

  2. 复习git

    git 常用点,详解 from my typora 文章目录 git 常用点,详解 git 模式解析 删除文件 方式一: 方式二: 远程库 配置忽略文件 查看版本库日志,以及版本回退 解决冲突 替换我 ...

  3. jQuery中ajax请求的六种方法(三、一):$.ajax()方法

    1.基础的$.ajax()方法 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"&g ...

  4. 关于Junit中Assert已经过时

    在junit4.12之后,Assert就过时了,提供了TestCase来取代: 同样在TestCase中原本比较常见的一些方法也已经取消了,例如:assertNotEquals.assertThat. ...

  5. Spring源码解析之ConfigurationClassPostProcessor(三)

    在上一章笔者介绍了ConfigurationClassParser.doProcessConfigurationClass(...)方法,在这个方法里调用了processImports(...)方法处 ...

  6. 【CSS简介、基础选择器、字体属性、文本属性、引入方式】前端小抄(2) - Pink老师自学笔记

    [CSS简介.基础选择器.字体属性.文本属性.引入方式]前端小抄(2) 本学习笔记是个人对 Pink 老师课程的总结归纳,转载请注明出处! 一.CSS简介 CSS 的主要使用场景就是布局网页,美化页面 ...

  7. PowerDotNet平台化软件架构设计与实现系列(01):基础数据平台

    本系列我将主要通过图片和少许文字讲解通过个人自研的PowerDotNet进行快速开发平台化软件产品. PowerDotNet不仅仅是包含像Newtonsoft.Json.Dapper.Quartz.R ...

  8. JDK和环境配置,eclipse安装与使用

    本博客部分参照https://blog.csdn.net/PGY0000/article/details/79256720 (记住要尊重别人的劳动产品) 原博客给的链接和后面的安装过程有点不一样,不能 ...

  9. MyBatis学习总结(四)——字段名与实体类属性名不相同的冲突的解决

    表中的字段名和表对应实体类的属性名称不一定都是完全相同的,这种情况下的如何解决字段名与实体类属性名不相同的冲突.如下所示: 一.准备演示需要使用的表和数据 CREATE TABLE my_user( ...

  10. shell循环语句while

    格式1: while 条件 do 执行命令 done 格式2: while 条件;do 命令 done 例子: while [ 1 -eq 1 ];do echo "这一步需要先修改/dat ...