题解 P1997 【faebdc 的烦恼】
Strelitzia · · 题解
题目传送门
题目要求你求区间的众数,很明显可以用莫队。
维护一个
注意
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
template<typename T>void read(T &x) {
T f = 1;x = 0;char s = getchar();
while(s < '0' || s > '9') {if(s == '-')f = -1;s = getchar();}
while(s >= '0' && s <= '9') {x = x * 10 + s - '0';s = getchar();}
x *= f;
}
template<typename T>void print(T x) {
if(x < 0) putchar('-'),x = -x;
if(x > 9) print(x / 10);
putchar(x % 10 + '0');
}
const int maxn = 200005;
int n,m,res,a[maxn],b[maxn],pos[maxn],cnt[maxn],ans[maxn],sum[maxn];
struct node {
int l,r,id;
bool operator <(node y) const {
return pos[this->l] ^ pos[y.l] ? this->l < y.l : (pos[this->l] & 1 ? this->r < y.r : this->r > y.r);
}
}ask[maxn];
bool cmp(int x,int y) {
return a[x] < a[y];
}
void Add(int x) {
sum[cnt[x]] --;
sum[++ cnt[x]] ++;
res = max(cnt[x],res);
}
void Sub(int x) {
if (cnt[x] == res && sum[cnt[x]] == 1) res --;
sum[cnt[x]] --;
sum[-- cnt[x]] ++;
}
int main () {
read(n);read(m);
int t = sqrt(n);
for (int i = 1 ; i <= n ; ++ i) {
read(a[i]);pos[i] = i / t;
a[i] += 1e5;
}
for (int i = 1 ; i <= m ; ++ i) {
read(ask[i].l);read(ask[i].r);
ask[i].id = i;
}
sort(ask + 1,ask + 1 + m);
int l = 1,r = 0;
for (int i = 1 ; i <= m ; ++ i) {
while (l > ask[i].l) Add(a[-- l]);
while (r < ask[i].r) Add(a[++ r]);
while (l < ask[i].l) Sub(a[l ++]);
while (r > ask[i].r) Sub(a[r --]);
ans[ask[i].id] = res;
}
for (int i = 1 ; i <= m ; ++ i) print(ans[i]),putchar('\n');
return 0;
}