RMQ问题
st表预处理,时间复杂度nlogN,适用于n较小,一般在1e5级别,查询m非常的情况下,很适合用st表预处理,然后查询区间最值,先把模板给出来。
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int n, m, a[N];
struct rmp
{
int f[N][50], lg[N] = {-1};
void init()
{
for(int i = 1; i <= n; ++i) f[i][0] = a[i];
for(int i = 1; i <= n; ++i) lg[i] = lg[i >> 1] + 1;
for(int j = 1; j <= lg[n]; ++j)
for(int i = 1; i + (1 << j) - 1 <= n; ++i)
f[i][j] = max(f[i][j - 1], f[i + (1 << (j - 1))][j - 1]);
}
int query(int x, int y)
{
int s = lg[y - x + 1];
return max(f[x][s], f[y - (1 << s) + 1][s]);
}
}st;
signed main()
{
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; ++i) scanf("%d", &a[i]);
st.init();
int l, r;
while(m-- && scanf("%d%d", &l, &r))
{
printf("%d\n", st.query(l, r));
}
return 0;
}
Frequent values(st表)
既然是连续的,相同的值连在一起,预处理每个值出现了多少次,然后st表处理,然后分块的思想去搞
#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<stack>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 1e5 + 100;
int n, q;
int a[N], b[N], L[N], R[N], cnt, pos[N];
int f[N][50], clg[N] = {-1};
void init(int len)
{
for(int i = 1; i <= len; ++i) f[i][0] = b[i];
for(int i = 1; i <= len; ++i) clg[i] = clg[i >> 1] + 1;
for(int j = 1; j <= clg[len]; ++j)
for(int i = 1; i + (1 << j) - 1 <= len; ++i)
f[i][j] = max(f[i][j - 1], f[i + (1 << (j - 1))][j - 1]);
}
int query(int x, int y)
{
if(x > y) return 0;
int s = clg[y - x + 1];
return max(f[x][s], f[y - (1 << s) + 1][s]);
}
signed main()
{
while(scanf("%d", & n) && n)
{
scanf("%d", &q);
memset(b, 0, sizeof b);
a[0] = 1e6 + 1;
for(int i = 1; i <= n; ++i)
{
scanf("%d", &a[i]);
pos[i] = (a[i] == a[i - 1] ? cnt : ++cnt);
b[cnt]++;
if(a[i] == a[i - 1]) L[i] = L[i - 1];
else L[i] = i;
}
R[n] = n;
for(int i = n - 1; i >= 0; --i)
{
if(a[i] == a[i + 1]) R[i] = R[i + 1];
else R[i] = i;
}
init(cnt);
int l, r;
while(q-- && scanf("%d%d", &l, &r))
{
if(pos[l] == pos[r]) printf("%d\n", r - l + 1);
else
{
int x = R[l] - l + 1;
int y = r - L[r] + 1;
int z = query(pos[l] + 1, pos[r] - 1);
printf("%d\n", max(max(x, y), z));
}
}
}
return 0;
}

浙公网安备 33010602011771号