前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >LuoguP3793 由乃救爷爷

LuoguP3793 由乃救爷爷

作者头像
yzxoi
发布2022-09-19 13:21:09
2450
发布2022-09-19 13:21:09
举报
文章被收录于专栏:OI

LuoguP3793 由乃救爷爷

Description

题目链接:P3793

给定一个 n 个数的序列,有 m 个询问,每次询问区间最大值。

1\leq n,m\leq 2\times 10^7,保证数据随机。

Solution

考虑分块。

如果朴素分块肯定是不能过的 O(N\sqrt{N}),但是这题并没有修改操作,所以考虑先预处理出第 l 个块到第 r 个块的最大值、第 i 个块的前缀最大值、第 i 个块的后缀最大值。

每次询问的时候如果 l,r 在同一个块内可以直接暴力,出现此情况应该是 \frac{1}{\sqrt{N}},而单次暴力复杂度为 O(\sqrt{N}),所以总期望复杂度是 O(N)

如果不在同一块内直接利用预处理出的结果 O(1) 即可。

所以总的时间复杂度是 O(N)

Code

代码语言:javascript
复制
#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define W while
#define I inline
#define RI register int
#define LL long long
#define Cn const
#define CI Cn int&
#define gc getchar
#define D isdigit(c=gc())
#define pc(c) putchar((c))
#define min(x,y) ((x)<(y)?(x):(y))
#define max(x,y) ((x)>(y)?(x):(y))
using namespace std;
namespace Debug{
    Tp I void _debug(Cn char* f,Ty t){cerr<<f<<'='<<t<<endl;}
    Ts I void _debug(Cn char* f,Ty x,Ar... y){W(*f!=',') cerr<<*f++;cerr<<'='<<x<<",";_debug(f+1,y...);}
    Tp ostream& operator<<(ostream& os,Cn vector<Ty>& V){os<<"[";for(Cn auto& vv:V) os<<vv<<",";os<<"]";return os;}
    #define gdb(...) _debug(#__VA_ARGS__,__VA_ARGS__)
}using namespace Debug;
namespace FastIO{
    Tp I void read(Ty& x){char c;int f=1;x=0;W(!D) f=c^'-'?1:-1;W(x=(x<<3)+(x<<1)+(c&15),D);x*=f;}
    Ts I void read(Ty& x,Ar&... y){read(x),read(y...);}
    Tp I void write(Ty x){x<0&&(pc('-'),x=-x,0),x<10?(pc(x+'0'),0):(write(x/10),pc(x%10+'0'),0);}
    Tp I void writeln(Cn Ty& x){write(x),pc('\n');}
}using namespace FastIO;
Cn int N=2e7,S=10000,M=N/S;
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 fread(){using namespace GenHelper;int a=rand_()&32767;int b=rand_()&32767;return a*32768+b;}
int n,m,seed,a[N+5],F[M+5][M+5],G[M+5],L[M+5][S+5],R[M+5][S+5];
unsigned long long Ans;
I int Q(CI l,CI r){
    RI X=0;if(l/S==r/S){RI i;for(i=l;i<=r;i++) X=max(X,a[i]);return X;}//直接暴力
    if(l/S+2<=r/S) X=F[l/S+2][r/S];X=max(X,max(R[l/S+1][l%S],L[r/S+1][r%S]));return X; 
}
int main(){
    RI i,j,l,r;read(n,m,seed),srand(seed);for(i=0;i<n;i++) a[i]=fread(),G[i/S+1]=max(G[i/S+1],a[i]);
    for(i=1;i<=(n-1)/S+1;i++) for(j=i;j<=(n-1)/S+1;j++) F[i][j]=max(F[i][j-1],G[j]);//块间最值
    for(i=0;i<n;i++) !(i%S)?L[i/S+1][i%S]=a[i]:L[i/S+1][i%S]=max(L[i/S+1][i%S-1],a[i]);
    for(i=n-1;~i;i--) R[i/S+1][i%S]=max(R[i/S+1][i%S+1],a[i]);//前缀&后缀最大值
    W(m--) l=fread()%n,r=fread()%n,l>r&&(swap(l,r),0),Ans+=Q(l,r);
    return writeln(Ans),0;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-04-08 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • LuoguP3793 由乃救爷爷
    • Description
      • Solution
        • Code
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档