牛客多校第五场-K-Bag(思维+实现)

传送门
只要维护一个切割点数组cut[i],表明从1~i的切割是有效的,且可与后半部分拼接。维护好cut后只要从后往前再扫一遍即可。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define MAXN 2005005
int n,k;
int a[MAXN];
int cut[MAXN];
unordered_map<int,int>mp;
int main()
{
    
    
    int t;
    cin>>t;
    while(t--)
    {
    
    
        mp.clear();
        scanf("%d%d",&n,&k);
        int flag=0;
        for(int i=1;i<=n;i++) {
    
    
            cut[i]=0;
            scanf("%d", a + i);
            if(a[i]>k)flag=1;
        }
        if(flag){
    
    cout<<"NO"<<endl;continue;}
        int cnt=0;
        cut[0]=1;
        for(int i=1;i<=n;i++)
        {
    
    
            if(i>k){
    
    
                mp[a[i-k]]--;
                if(mp[a[i-k]]==0)cnt--;
            }
            mp[a[i]]++;
            if(mp[a[i]]==1)cnt++;
            if(cnt==k||cnt==i)cut[i]=i>=k?cut[i-k]:1;
        }
        cnt=0;mp.clear();
        for(int i=n;i>=max(0,n-k);i--)
        {
    
    
            if(cnt==n-i&&cut[i])flag=1;
            mp[a[i]]++;
            if(mp[a[i]]==1)cnt++;
        }
        printf(flag?"YES\n":"NO\n");
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_43353639/article/details/107624634