2020牛客多校第六场 K-Bag

题目

在这里插入图片描述

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

思路

先枚举起点 注意起点要0~k-1
把每个下标对应的起点标记起来
滑动窗口每次取K个判定

代码

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define ll long long
int a[5000100],cnt[5000100];
bool vis[5000100];	
unordered_map<ll,ll> mp,mp2;
signed main()
{
    ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    int t;
    cin>>t;
    while(t--){
    	int n,k;
    	cin>>n>>k;
    	for(int i=1;i<=n;i++) cin>>a[i],cnt[i]=0,vis[i]=0;
    	mp.clear();
    	vis[0]=0,cnt[0]=0;
    	if(k>=n){   	
			mp2.clear();
    		bool flag=0,flag1=0;
    		for(int i=1;i<=n;i++){
    			if(a[i]>k) flag1=1;
    			if(mp2[a[i]]&&mp[a[i]]>=1) flag1=1;
				mp[a[i]]++;
				if(mp[a[i]]==2) flag=1;
				if(flag) mp2[a[i]]=1;
			}
			if(flag1) cout<<"NO"<<endl;
			else cout<<"YES"<<endl;
		}
		else{
			int num=0;
			for(int i=0;i<=k-1;i++){
				//vis[i]=0;
				int m=i+k;
				while(m<=n){
					cnt[m]=i;
					m+=k;	
				}
			}		
			bool flag1=0;
		//	for(int i=1;i<=n;i++) cout<<cnt[i]<<endl;
			for(int i=1;i<=n;i++){
				if(i<=k-1){
					mp[a[i]]++;
					if(mp[a[i]]==2) num++; 
					if(num) vis[i]=1;
					if(a[i]>k) flag1=1;
				}
				else{
					mp[a[i]]++;
					if(mp[a[i]]==2) num++; 	
					if(i-k>0){if(mp[a[i-k]]==2) num--;mp[a[i-k]]--;}
				//	cout<<mp[a[i]]<<" "<<i<<endl;
				//	cout<<cnt[i]<<" "<<vis[cnt[i]]<<endl;
					if(num) vis[cnt[i]]=1;
					if(a[i]>k) flag1=1;
				//	cout<<num<<" "<<a[i]<<" "<<vis[cnt[i]]<<endl;
				}
			}
			for(int i=n-k+1;i<=n;i++){
			//	cout<<a[i]<<" "<<i<<" "<<mp[a[i]]<<endl;
				if(mp[a[i]]){
					if(mp[a[i]]==2) num--;
					mp[a[i]]--;}
				if(num){
					if(i<=k-1) vis[i]=1;
					else vis[cnt[i]]=1;}
				//cout<<a[i]<<" "<<i<<" "<<mp.size()<<endl;
			//	for(auto i:mp) cout<<i.first<<" "<<i.second<<endl;
			}
			bool flag=0;
			for(int i=0;i<=k-1;i++) if(!vis[i]) flag=1;
			if(!vis[cnt[k]]) flag=1;
			if(flag&&!flag1) cout<<"YES"<<endl;
			else cout<<"NO"<<endl;
		}
	}
    return 0;
}

猜你喜欢

转载自blog.csdn.net/kosf_/article/details/107650429
今日推荐