题目链接-K.K-Bag
题目大意
一种叫 k − b a g k-bag k−bag的序列,这类序列由若干个从 1 − k 1-k 1−k的排列依次排列组成,例如 1 , 2 , 3 , 2 , 1 , 3 , 3 , 2 , 1 1,2,3,2,1,3,3,2,1 1,2,3,2,1,3,3,2,1就是一个3-bag序列,现在又定义了 p a r t k − b a g part\ k-bag part k−bag,如果一个序列是一个 k − b a g k-bag k−bag的连续子串,那么这个序列就叫做 p a r t k − b a g part\ k-bag part k−bag序列,请你判断一个序列是否是 p a r t k − b a g part\ k-bag part k−bag序列
解题思路
滑 动 窗 口 问 题 滑动窗口问题 滑动窗口问题
NO
f[]
来记录该位置可不可以切f[i]!=0
),则说明存在一种方案满足该序列是一个 p a r t k − b a g part\ k-bag part k−bag附上代码
#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include
#define int long long
#define lowbit(x) (x &(-x))
#define endl '\n'
using namespace std;
const int INF=0x3f3f3f3f;
const int dir[4][2]={-1,0,1,0,0,-1,0,1};
const double PI=acos(-1.0);
const double e=exp(1.0);
const double eps=1e-10;
const int M=1e9+7;
const int N=5e6+10;
typedef long long ll;
typedef pair<int,int> PII;
typedef unsigned long long ull;
int a[N],f[N];
unordered_map<int,int> mp;
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int t;
cin>>t;
while(t--){
mp.clear();
int n,k,ass=0,cnt=0;
cin>>n>>k;
for(int i=1;i<=n;i++){
cin>>a[i];
if(a[i]>k) ass=1;
}
if(ass){
cout<<"NO"<<endl;
continue;
}
memset(f,0,sizeof f);
f[0]=1;
for(int i=1;i<=n;i++){
if(i>k){
mp[a[i-k]]--;
if(mp[a[i-k]]==0) cnt--;
}
if(mp[a[i]]==0) cnt++;
mp[a[i]]++;
if(cnt==k||cnt==i)
f[i]=i-k>=0?f[i-k]:1;
}
cnt=0;
mp.clear();
for(int i=n;i>=max(n-k,0ll);i--){
if(f[i]&&cnt==n-i){
ass=1;
break;
}
if(mp[a[i]]==0) cnt++;
mp[a[i]]++;
}
if(ass) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
return 0;
}