http://codeforces.com/contest/1631/problem/D
只要保证“[x,y]内的数量-[x,y]外的数量>=k”,则一定存在对应的划分。
那么可以分为两个独立小问题:(1)如何确定x与y满足“[x,y]内的数量-[x,y]外的数量>=k”(2)如何找出划分。
(1)是典型最大最小化,二分即可
#include <bits/stdc++.h>
using namespace std;
const int maxn=2e5+10;
int ary[maxn],book[maxn],sum[maxn];
int n,k,x,y,ansx,ansy;
void judge(int len)
{
int i;
for(i=1;i+len-1<=n;i++){
if(2*(sum[i+len-1]-sum[i-1])-n>=k){
x=i,y=i+len-1;
return;
}
}
}
void solve()
{
int i,s0,s1,p,cnt;
s0=0,s1=0,p=0,cnt=0;
for(i=1;i<=n;i++){
if(cnt==k-1){
printf("%d %d\n",p+1,n);
return;
}
if(ansx<=ary[i]&&ary[i]<=ansy){
s1++;
}
else{
s0++;
}
if(s0<s1){
printf("%d %d\n",p+1,i);
s0=0,s1=0,p=i,cnt++;
}
}
}
int main()
{
int t,i;
int l,r,mid;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&k);
for(i=1;i<=n;i++){
book[i]=0;
}
for(i=1;i<=n;i++){
scanf("%d",&ary[i]);
book[ary[i]]++;
}
for(i=1;i<=n;i++){
sum[i]=sum[i-1]+book[i];
}
l=1,r=n;
while(l<=r){
mid=(l+r)/2,x=-1,y=-1;
judge(mid);
if(x!=-1){
r=mid-1;
ansx=x,ansy=y;
}
else{
l=mid+1;
}
}
printf("%d %d\n",ansx,ansy);
solve();
}
return 0;
}