P3793-由乃救爷爷【分块,ST表】
正题
题目链接: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表】的更多相关文章
- Luogu3793 由乃救爷爷 分块、ST表
传送门 因为昨天写暴力写挂在UOJ上用快排惨遭卡常,所以今天准备写一个卡常题消遣消遣,然后时间又垫底了QAQ 这道题显然需要支持一个\(O(N)\)预处理\(O(1)\)查询的ST表,显然普通的ST表 ...
- [洛谷P3793]由乃救爷爷
题目大意:有$n(n\leqslant2\times10^7)$个数,$m(m\leqslant2\times10^7)$个询问,每次询问问区间$[l,r]$中的最大值.保证数据随机 题解:分块,处理 ...
- 【JZOJ5064】【GDOI2017第二轮模拟day2】友好城市 Kosarajo算法+bitset+ST表+分块
题面 在Byteland 一共有n 座城市,编号依次为1 到n,这些城市之间通过m 条单向公路连接. 对于两座不同的城市a 和b,如果a 能通过这些单向道路直接或间接到达b,且b 也能如此到达a,那么 ...
- Luogu 3793 由乃救爷爷
\(\verb|Luogu 3793 由乃救爷爷|\) rmq,数据随机 \(n,\ m\leq 2\times10^7\) lxl ST表 分块,大小设为 \(x\) 预处理每个块两端到块内每个点的 ...
- [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 ...
- [BZOJ1012] [JSOI2008] 最大数maxnumber (ST表)
Description 现在请求你维护一个数列,要求提供以下两种操作:1. 查询操作.语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值.限制:L不超过当前数列的长度.2. 插 ...
- CF1039E Summer Oenothera Exhibition 贪心、根号分治、倍增、ST表
传送门 感谢这一篇博客的指导(Orzwxh) $PS$:默认数组下标为$1$到$N$ 首先很明显的贪心:每一次都选择尽可能长的区间 不妨设$d_i$表示在取当前$K$的情况下,左端点为$i$的所有满足 ...
- CF1039E Summer Oenothera Exhibition 根号分治,LCT,ST表
CF1039E Summer Oenothera Exhibition LG传送门 根号分治好题. 可以先看我的根号分治总结. 题意就是给出长度为\(n\)的区间和\(q\)组询问以及一个\(w\), ...
- 【笔记】自学ST表笔记
自学ST表笔记 说实话原先QBXT学的ST表忘的差不多了吧...... 我重新自学巩固一下(回忆一下) 顺便把原先一些思想来源的原博发上来 一.ST表简介 ST表,建表时间\(O(n\cdot log ...
随机推荐
- 【权限管理】Spring Security 执行流程
转自:https://blog.csdn.net/weixin_37689658/article/details/92752890 1.基本配置使用 (1)创建配置类 创建一个配置类SecurityC ...
- SpringBoot集成<个推推送> Maven 下载jar包异常处理本地打包下载
问题描述 公司需要对用户进行消息推送,选择了个推,由于是Java进行开发,个推操作文档, 这是官网上安装的方式,可是不成功,无论怎么样都无法把Jar包下载下来! MAVEN方式(本人测试Jar无法下载 ...
- Centos7 安装 redis4.x
一.安装redis 第一步:下载redis安装包 wget http://download.redis.io/releases/redis-4.0.6.tar.gz [root@iZwz991stxd ...
- struts2思想学习(一)
OOP 面向对象编程 AOP 面向切面编程 而在struts2 处处体现了面向切面编程的思想(动态代理最典型)! 拦截器其实也是面向切面编程!拦截器切断了所有请求到action的操作 并做了很多的前提 ...
- react项目实现多语言切换
网站的语言切换功能大家都见过不少,一般都是一个下拉框选择语言,如果让我们想一下怎么实现这个功能,我相信大家都是有哥大概思路,一个语言切换的select,将当前的选择的语言存在全局,根据这个语言的key ...
- Spring Mvc原理分析(一)
Servlet生命周期了解 Servlet的生命(周期)是由容器(eg:Tomcat)管理的,换句话说,Servlet程序员不能用代码控制其生命. 加载和实例化:时机取决于web.xml的定义,如果有 ...
- 自己封装一个Object.freeze()方法
1.遍历所有属性和方法 2.修改遍历到的属性的描述 3.Object.seal() Object.defineProperty(Object,'freezePolyfill',{ value:func ...
- Panel添加边框颜色和边框粗细调整
Panel控件添加边框颜色 C# WinForm窗体控件Panel修改边框颜色以及边框宽度方法 - JiYF - 博客园 (cnblogs.com) 1.新建一个用户控件的项目,如下: 2.添加一个P ...
- Python中的私有属性私有方法、类属性类方法以及单例设计模式
私有属性是对象不希望公开的属性,私有方法是对象不希望公开的方法.在定义私有属性和私有方法时,在属性或者方法前,加上__(两个下划线) 公有方法可以通过对象名直接调用,私有方法不能通过对象名直接调用,只 ...
- Netty ServerBootstrap如何绑定端口
这篇讲netty服务端ServerBootstrap如何启动 前言 BootStrap在netty的应用程序中负责引导服务器和客户端.netty包含了两种不同类型的引导: 使用服务器的ServerBo ...