正题

题目链接: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. 【转】SpringCloud学习

    Spring Cloud Alibaba与Spring Boot.Spring Cloud之间不得不说的版本关系   这篇博文是临时增加出来的内容,主要是由于最近连载<Spring Cloud ...

  2. Java程序设计学习笔记(三)—— IO

    时间:2016-3-24 11:02 --IO流(Input/Output)     IO流用来处理设备之间的数据传输.    Java对数据的操作是通过流的方式.    Java对于操作流的对象都在 ...

  3. tree命令出现乱码

    alias tree='tree --charset ASCII'就可以了

  4. Promise.race()

    Promise.race([ ])---race竞赛,只要有一个决议了,就返回一个promise实例(对应resolve()或reject( )中参数值: 1.与Promise.all()对应的,还有 ...

  5. ubuntu软件工具推荐

    时间:2019-04-11 记录:PangYuaner 标题:串口调试利器--Minicom配置及使用详解 地址:https://www.cnblogs.com/wonux/p/5897127.htm ...

  6. 关于ubuntu使用的那些事儿

    时间:2019-04-09 整理:PangYuaner 标题:Ubuntu18.04安装微信(Linux通用) 地址:https://www.cnblogs.com/dotnetcrazy/p/912 ...

  7. C#窗体间互相传值

    Demo窗体图片,Form1 Demo窗体图片,Form2 公共委托 using System; namespace _DeleFrm{  public class Dele  {    public ...

  8. 基于Linux系统Samba服务器的部署

    1.基础信息 用 Internet 文件系统 CIFS(Common Internet File System)是适用于MicrosoftWindows 服务器和客户端的标准文件和打印机共享系统信息块 ...

  9. ELK数据迁移,ES快照备份迁移

    通过curl命令或者kibana快照备份,恢复的方式进行数据迁移 环境介绍 之前创建的ELK 因为VPC环境的问题,需要对ELK从新部署,但是还需要保留现有的数据,于是便有了这篇文档. 10.0.20 ...

  10. 从环境搭建到打包使用TypeScript

    目录 1.TypeScript是什么 2.TypeScript增加了什么 3.TypeScript环境的搭建 4.TypeScript的基本类型 5.TypeScrip编译选项 6.TypeScrip ...