分块

记得bl[0] = bl[n+1] = 一个很奇怪的数

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <algorithm>
 4 #include <cstring>
 5 #include <cmath>
 6 #define REP(i, s, n) for(int i = s; i <= n; i ++)
 7 #define RAP(i, n, s) for(int i = n; i >= s; i --)
 8 #define id bl[i]
 9 using namespace std;
10 const int INF = -1u >> 1;
11 const int maxn = 10000 + 10;
12 const int maxb = 100 + 10;
13 int A[maxn], n, Q, SIZE;
14 int bl[maxn], w[maxb], pre[maxn], suf[maxn];
15 int query(int L, int R){
16     int ret = -INF;
17     if(bl[L] == bl[R]) REP(i, L, R) ret = max(ret, A[i]);
18     else {
19         REP(i, bl[L] + 1, bl[R] - 1) ret = max(ret, w[i]);
20         ret = max(ret, pre[R]); ret = max(ret, suf[L]);
21     }
22     return ret;
23 }
24 void read(int &x){
25     x = 0; int sig = 1; char ch = getchar();
26     while(!isdigit(ch)) { if(ch == '-') sig = -1; ch = getchar(); }
27     while(isdigit(ch)) x = 10 * x + ch - '0', ch = getchar();
28     x *= sig; return ;
29 }
30 void init(){
31     read(n); read(Q);
32     SIZE = sqrt(n);
33     REP(i, 1, SIZE) w[i] = -INF;
34     bl[0] = bl[n + 1] = n + 1;
35     REP(i, 1, n) read(A[i]), id = (i - 1) / SIZE + 1, w[id] = max(w[id], A[i]);
36     REP(i, 1, n) if(id != bl[i - 1]) pre[i] = A[i]; else pre[i] = max(pre[i - 1], A[i]);
37     RAP(i, n, 1) if(id != bl[i + 1]) suf[i] = A[i]; else suf[i] = max(suf[i + 1], A[i]);
38     return ;
39 }
40 void work(){
41     int L, R;
42     while(Q --) read(L), read(R), printf("%d
", query(L, R));
43     return ;
44 }
45 void print(){
46 
47     return ;
48 }
49 int main(){
50     init();
51     work();
52     print();
53     return 0;
54 }
原文地址:https://www.cnblogs.com/chxer/p/4419708.html