这道题我参考了两位大佬的思路
https://blog.youkuaiyun.com/littlegoldgold/article/details/107622720
https://blog.youkuaiyun.com/ding_ning123/article/details/107619213
题解
首先由于数据太大所以我们将数组进行离散化处理
关于离散化的讲解https://oi-wiki.org//misc/discrete/
sort(b + 1, b + n + 1);//先对b数组(b数组和a数组相等)进行排序,“去重”的前提是排好序的数组
int cnt = unique(b + 1,b + n + 1) - b - 1;//返回“去重”之后的数组个数
for(int i = 1; i <= n ; i++)
{
a[i] = lower_bound(b + 1, b + 1 + cnt ,a[i]) - b;//找去重后对应的下标
}
其次我们需要借助数组来统计每个区间的最大长度
- ++
表示没有遇到重复的数字,--
表示遇到一个重复的数字即一个区间的结束
- 如果
== 0表示这个数字没有出现过
- 最后利用前缀和的思想来统计每段区间的最大长度
int p = 1;
for(int i = 1; i <= n ; i++)
{
while(!pre[a[p]] && p <= n)//没有遇到相邻的数
{
pre[a[p]]++;
p++;
}
--pre[a[i]];
len[i] = p - i;
}
最后枚举起点的位置,然后往后跳,只要遇到一个区间的长度不为k就不行
int sc = 0;
//由于有些样例第一个区间不等于k,而我们要枚举的是前端部分,所以起点的枚举必须小于等于min(k,len[1] + 1)
for(int st = 1 ; st <= min(k,len[1] + 1); st++)
{
flag = true;
for(int i = st; i <= n; i += k)
{
if( i + len[i] >= n + 1)
{
continue;
}
else if(len[i] != k)
{
flag = false;
break;
}
}
if(flag)
{
sc = 1;
break;
}
}
完整代码
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N = 2 * 1e6 + 6;
int a[N],b[N],pre[N],len[N];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t;
cin >> t;
while(t--)
{
int n,k;
cin >> n >> k;
bool flag = true;
for(int i = 1 ; i <= n ; i++)
{
cin >> a[i];
b[i] = a[i];
if(a[i] > k || a[i] < 0)
{
flag = false;
}
}
if(!flag)
{
cout << "NO" << endl;
continue;
}
sort(b + 1, b + n + 1);//先对b数组(b数组和a数组相等)进行排序,“去重”的前提是排好序的数组
int cnt = unique(b + 1,b + n + 1) - b - 1;//返回“去重”之后的数组个数
for(int i = 1; i <= n ; i++)
{
a[i] = lower_bound(b + 1, b + 1 + cnt ,a[i]) - b;//找去重后对应的下标
}
int p = 1;
for(int i = 1; i <= n ; i++)
{
while(!pre[a[p]] && p <= n)//没有遇到相邻的数
{
pre[a[p]]++;
p++;
}
--pre[a[i]];
len[i] = p - i;
}
int sc = 0;
//由于有些样例第一个区间不等于k,而我们要枚举的是前端部分,所以起点的枚举必须小于等于min(k,len[1] + 1)
for(int st = 1 ; st <= min(k,len[1] + 1); st++)
{
flag = true;
for(int i = st; i <= n; i += k)
{
if( i + len[i] >= n + 1)
{
continue;
}
else if(len[i] != k)
{
flag = false;
break;
}
}
if(flag)
{
sc = 1;
break;
}
}
if(sc)
{
cout << "YES" << endl;
}
else
{
cout << "NO" << endl;
}
}
return 0;
}