思路:因为是定长区间,因此我们可以利用滑动窗口维护定长区间的众数的数量
AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MOD = 998244353;
const int N = 2e5 + 10;
ll a[N];
ll b[N];//前i个数的相同的数的最大值
int main()
{
int t;
cin >> t;
while(t --){
ll n, k, q;
cin >> n >> k >> q;
for(int i = 1; i <= n; i ++)
{
cin >> a[i];
a[i] -= i;
}
//求每个区间为k的区间众数的数量
//看到定长想到滑动区间
map<ll, ll>ma, cnt;//记录数量
for(int i = 1; i <= n; i ++)
{
if(cnt.count(ma[a[i]]))//相当于对右边界进行操作
{
cnt[ma[a[i]]] -= 1;
if(!cnt[ma[a[i]]]) cnt.erase(ma[a[i]]);
}
ma[a[i]] += 1;
cnt[ma[a[i]]] += 1;
//前k个数还没到达窗口最远
if(i < k) continue;
//因为区间长度已经确定为k了,因此我们确定了左区间,右区间也随之确定了
b[i - k + 1] = cnt.rbegin() ->first;//代表反向开始的第一个元素,即众数
// cout << b[1] << "sss" << endl;
cnt[ma[a[i - k + 1]]] -= 1;//因为开始窗口滑动了因此也需要考虑左边界了
if(!cnt[ma[a[i - k + 1]]]) cnt.erase(ma[a[i - k + 1]]);
ma[a[i - k + 1]] -= 1;//左边界ma也要参与了
if(ma[a[i - k + 1]]) cnt[ma[a[i - k + 1]]] += 1;
}
while(q --){
ll l, r;
cin >> l >> r;
cout << k - b[l] << endl;
}
}
return 0;
}
标签:cnt,ma,G1,int,ll,cin,version,众数,区间
From: https://blog.csdn.net/2301_80882026/article/details/142180996