zoukankan      html  css  js  c++  java
  • 2020牛客暑期多校训练营(第六场)K

    Description

    给定一个长度为 (n) 的序列,判定它是否为一个由多个 (1 sim k) 全排列顺序连接起来的序列的子串。

    Solution

    首先如果原序列中有不在 ([1,k]) 中的元素则直接退出。

    考虑每个元素和它上一次出现的位置,如果其间的距离 (le k),则显然 ([lastpos,pos-1]) 之间必有一个分割点。

    环上差分有点麻烦,考虑直接模拟,用 (sum) 记录当前的前缀和,每经过一个位置就将这个前缀和加到这个位置取模后对应位置的 (ans) 上即可。

    正确性的保证基于我们所列出的所有区间其长度一定 (le k)

    #include <bits/stdc++.h>
    using namespace std;
    
    #define int long long 
    const int N = 1000005;
    
    int n,k,a[N],b[N],ans[N];
    
    void solve()
    {
        scanf("%lld%lld",&n,&k);
        map <int,int> mp;
        int tot=0;
        for(int i=0;i<=n+1;i++) a[i]=b[i]=ans[i]=0;
        for(int i=1;i<=n;i++) 
        {
            scanf("%lld",&a[i]);
            if(a[i]>k)
            {
                puts("NO");
                return;
            }
            int pos=i,lastpos=mp[a[i]];
            if(lastpos>0 && pos-lastpos<k)
            {
                b[lastpos]++;
                b[pos]--;
                tot++;
            }
            mp[a[i]]=i;
        }
        int sum=0;
        for(int i=1;i<=n;i++)
        {
            sum+=b[i];
            ans[i%k]+=sum;
        }
        if(*max_element(ans,ans+n+1)>=tot)
        {
            puts("YES");
        }
        else
        {
            puts("NO");
        }
        
    }
    
    signed main()
    {
        int t;
        scanf("%lld",&t);
        while(t--)
        {
            solve();
        }
        return 0;
    }
    
  • 相关阅读:
    RecycleView的万能适配器
    Android Fragment
    BottomNavigationBar底部导航条用法
    Bundle的用法
    登录页面(动态地与数据库匹配用户信息)
    LitePal用法详解
    BaseAdapter的优化
    Bmob使用心得
    字符串格式化
    元素NULL判断
  • 原文地址:https://www.cnblogs.com/mollnn/p/13773496.html
Copyright © 2011-2022 走看看