0
点赞
收藏
分享

微信扫一扫

CF 1631 D. Range and Partition 尺取 + 前缀和

杰森wang 2022-01-30 阅读 28

传送门

文章目录

目录:

题意:

给你一个长度为 n n n的数组 a a a以及 k k k,让你选择一个值域 [ x , y ] [x,y] [x,y],满足能将该数组分成连续的 k k k段并且每段中值域在 [ x , y ] [x,y] [x,y]内的个数严格大于不在其范围内的数的个数,要求你给出 [ x , y ] [x,y] [x,y]并且让 y − x y-x yx最小,让后给出分段的方案。

1 ≤ k ≤ n ≤ 2 e 5 , 1 ≤ a i ≤ n 1\le k\le n\le 2e5,1\le a_i\le n 1kn2e5,1ain

思路:

一开始想错了,二分了 x x x y y y还感觉很对。。。

可以发现 [ x , y ] [x,y] [x,y]这是一个连续的区间,我们可以利用这个进行尺取,现在问题就变成了如何检验给定 [ x , y ] [x,y] [x,y]是否合法。

我们将值域在 [ x , y ] [x,y] [x,y]内的数看成 1 1 1,不在值域内的数看成 − 1 -1 1,设新数组 p r e pre pre就是将 a a a换成 1 1 1 − 1 -1 1后的前缀和数组,那么一个子区间合法的条件就是 [ l , r ] [l,r] [l,r]满足 p r e [ r ] − p r e [ l − 1 ] > 0 pre[r]-pre[l-1]>0 pre[r]pre[l1]>0,顺着这个思路,我们不难发现分段方案就是在 p r e pre pre数组中找一个从0开始的上升序列,长度为 k + 1 k+1 k+1,那么最终 p r e [ n ] pre[n] pre[n]一定需要满足 p r e [ n ] > = k pre[n]>=k pre[n]>=k,此时就比较好搞了,我们先尺取求出来 [ x , y ] [x,y] [x,y],判断条件就是 p r e [ n ] > = k pre[n]>=k pre[n]>=k p r e [ n ] pre[n] pre[n]是所有数的和,只需要存一下当前数有几个即可,最后输出方案。

复杂度 O ( n ) O(n) O(n)

#include<bits/stdc++.h>
#define X first
#define Y second
#define L (u<<1)
#define R (u<<1|1)
#define Mid (tr[u].l+tr[u].r>>1)
#define pb push_back
using namespace std;

const int N=1000010,INF=0x3f3f3f3f,mod=1e9+7;
typedef long long LL;

int n,k;
int a[N],cnt[N];

void solve() {
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]),cnt[a[i]]++;
    int x,y,sum=-n;
    x=0; y=INF;
    for(int l=1,r=0;r<=n;) {
        while(r+1<=n&&sum<k) sum+=cnt[++r]*2;
        if(sum<k) break;
        if(r-l+1<y-x+1) x=l,y=r;
        sum-=cnt[l++]*2;
    }
    printf("%d %d\n",x,y);
    sum=0;
    int cntt=1;
    int l=1;
    for(int i=1;i<=n;i++) {
        if(a[i]>=x&&a[i]<=y) sum++;
        else sum--;
        if(sum==cntt) {
            cntt++;
            if(cntt==k+1) {
                printf("%d %d\n",l,n);
                break;
            }
            else printf("%d %d\n",l,i),l=i+1;
        }
    }
    for(int i=1;i<=n;i++) cnt[a[i]]=0;
}

int main() {
	int _; scanf("%d",&_);
	while(_--) {
		solve();
	}

}

举报

相关推荐

0 条评论