题目描述见链接 .
题意: 求区间内出现最多的数字出现的次数 .
使用 莫队, 记 表示 出现了几次, 再记 表示出现 次的数字有多少个,
表示答案,
- 添加 , 若 比 大, 则更新 .
- 删除 , 若 , 且 , 则说明修改前 是出现次数最多的唯一数字, 修改后就不存在出现 次的数字了, 答案变为 .
放上很久以前写的代码 …
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cmath>
#define _for(x, N, p) for(int i = x; i <= N; i += p)
const int maxn = 200005;
int N, M, Ans;
int Tong[maxn], num[maxn], A[maxn], B[maxn];
int Max_num, Max_index;
struct Query{ int L, R, block, index, Ans; } Q[maxn];
bool cmp(const Query &a, const Query &b){ return a.block==b.block?a.R<b.R:a.block<b.block; }
bool _cmp(const Query &a, const Query &b){ return a.index < b.index; }
void Add(int x){
num[Tong[x]] --;
Tong[x] ++;
num[Tong[x]] ++;
if (Max_num < Tong[x]) Max_num ++;
}
void Del(int x){
num[Tong[x]] --;
Tong[x] --;
num[Tong[x]] ++;
if (num[Max_num] == 0) Max_num --;
}
int main(){
scanf("%d %d", &N, &M);
int block_size = std::sqrt(N);
_for(1, N, 1) scanf("%d", &A[i]), B[i] = A[i];
std::sort(B+1, B+N+1);
int size = std::unique(B, B+N+1) - B;
_for(1, N, 1) A[i] = std::lower_bound(B+1, B+size+1, A[i]) - B;
_for(1, M, 1){
scanf("%d %d", &Q[i].L, &Q[i].R);
Q[i].block = Q[i].L / block_size + 1;
Q[i].index = i;
}
std::sort(Q+1, Q+M+1, cmp);
int l = 1, r = 0;
_for(1, M, 1){
while(l < Q[i].L) Del(A[l ++]);
while(l > Q[i].L) Add(A[-- l]);
while(r < Q[i].R) Add(A[++ r]);
while(r > Q[i].R) Del(A[r --]);
Q[i].Ans = Max_num;
}
std::sort(Q+1, Q+M+1, _cmp);
_for(1, M, 1) printf("-%d
", Q[i].Ans);
return 0;
}