2020牛客多校第六场 K题 K-Bag(思维题)

链接:https://ac.nowcoder.com/acm/contest/5671/K

 

题目描述

A sequence is called kkk-bag, if and only if it is put in order by some (maybe one) permutations of 111 to kkk. For example, 1,2,3,2,1,3,3,2,11,2,3,2,1,3,3,2,11,2,3,2,1,3,3,2,1 is a valid 333-bag sequence.
Roundgod is not satisfied with kkk-bag, so she put forward part-kkk-bag, which is a  contiguous subsequence of kkk-bag.
Wcy wants to know if the sequence of length nnn is a part-kkk-bag sequence.

输入描述:

The first line contains one integer T (1≤T≤20)T\ (1\le T\le 20)T (1T20), denoting the number of test cases. Then TTT test cases follow.
The first line of each test case contains two integers n,k (1≤n≤5⋅105,1≤k≤109)n,k\ (1\le n \le 5 \cdot 10^5,1\le k \le 10^9)n,k (1n5105,1k109).
The second line of each test case contains nnn integers indicate the sequence.
It is guaranteed that ∑n≤2⋅106\sum n \le 2\cdot 10^6n2106, the values of the sequence are between 111 and 10910^9109.

输出描述:

One line of each test case, if the sequence is a part-kkk-bag sequence, print "YES", otherwise print "NO".
示例1

输入

复制
1
8 3
2 3 2 1 3 3 2 1

输出

复制
YES


题解:考虑寻找开始循环的起点,可以发现从起点后,每次必然是隔开K个的。可以尝试枚举起点,K>>N,先离散化。Len【】是以i为起点长度为len【i】的一段序列是没有重复元素的。
   枚举起点判定,分两种情况后面长度还有K个及以上则每次需要要往后跳K个,即len【pos】=k才行,或者直接到末尾了pos+len【pos】-1=n。
#include <bits/stdc++.h>
#define IO_read ios::sync_with_stdio(false);cin.tie(0)
#define fre freopen("in.txt", "r", stdin)
#define _for(i,a,b) for(int i=a; i< b; i++)
#define _rep(i,a,b) for(int i=a; i<=b; i++)
#define inf 0x3f3f3f3f
#define lowbit(a) ((a)&-(a))
using namespace std;
typedef long long ll;
template <class T>
void read(T &x)
{
    char c; bool op=0;
    while(c=getchar(), c<'0'||c>'9') if(c=='-') op=1;
    x=c-'0';
    while(c=getchar(), c>='0'&&c<='9') x=x*10+c-'0';
    if(op) x=-x;
}
template <class T>
void write(T x)
{
    if(x<0) putchar('-'), x=-x;
    if(x>=10) write(x/10);
    putchar('0'+x%10);
}

const int maxn=1e6+5;
int T, n, k;
int a[maxn], b[maxn];
int pre[maxn], len[maxn];

int check()
{
    int ok=0;
    for(int st=1; st<=min(k, len[1]+1); st++)
    {
        for(int p=st; p<=n; p+=k)
        {
            if(p+len[p]-1==n){ok=1; break;}
            else if(len[p]^k) break;
        }
        if(ok) break;
    }
    return ok? true:false;
}

int main()
{
    read(T);
    while(T--)
    {
        read(n), read(k);
        _rep(i, 1, n) read(a[i]), b[i]=a[i];
        sort(b+1, b+1+n);
        int cnt=unique(b+1, b+1+n)-(b+1);
        _rep(i, 1, n) a[i]=lower_bound(b+1, b+1+cnt, a[i])-(b+1)+1;
        int p=1;
        for(int i=1; i<=n; i++)
        {
            while(p<=n && !pre[a[p]]) pre[a[p]]++, p++;
            pre[a[i]]--, len[i]=p-i;
        }
        printf(check()? "YES\n":"NO\n");
    }

    return 0;
}

 

posted @ 2020-07-29 14:30  N_Yokel  阅读(258)  评论(0编辑  收藏  举报