2020牛客多校第六場 K題 K-Bag(思維題)
阿新 • • 發佈:2020-07-29
連結: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 of111to 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 valid333-bag sequence.Roundgod is not satisfied with kkk-bag, so she put forward part-kkk-bag, whichis a contiguous subsequence of kkk-bag.
輸入描述:
The first line contains one integer T(1≤T≤20)T\ (1\le T\le 20)T(1≤T≤20), denoting the number of test cases. ThenTTTtest 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(1≤n≤5⋅105,1≤k≤109).輸出描述:
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; }