LuoguP3793 由乃救爷爷

2022-09-19 13:21:09 浏览数 (1)

LuoguP3793 由乃救爷爷

Description

题目链接:P3793

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

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

Solution

考虑分块。

如果朴素分块肯定是不能过的 O(Nsqrt{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 '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;
}
ode

0 人点赞