2019年杭电多校训练1012

Posted yzxqq

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2019年杭电多校训练1012相关的知识,希望对你有一定的参考价值。

 
题意:给出n,c,k。
接着给出n个数字(在1~c之间),问最长的区间长度。该区间满足任意一个出现的数字至少出现k次。

思路:
我们可以把可能满足条件的区间进行判断,然后按区间内不符合条件的数的下标进行再次分区间,再次进行判断。
一直到所有的可能满足条件的区间都被判断完。

坑点:
在分区间时,对于边界的处理比较繁琐,(l,r)与不满足条件的数的下标的关系要特别注意。
#include<bits/stdc++.h>
using namespace std;
#define met(a,b) memset(a,b,sizeof(a))
int a[100009];
int ans=0;
map<int, vector<int> >pos;
int n,c,k;
void dfs(int l,int r)

    //cout<<l<<"............."<<r<<endl;
    if(r-l+1<k) return;
    if(l==r)
    
        if(k<=1)ans=max(ans,1);
        return ;
    
    else if(r<l) return ;
    int i=0;
    for( i=l; i<=r; i++)
            int tl=lower_bound(pos[a[i]].begin(),pos[a[i]].end(),l)-pos[a[i]].begin();
            int tr=upper_bound(pos[a[i]].begin(),pos[a[i]].end(),r)-pos[a[i]].begin();

            if(tr-tl<k) break;
    
    if(i==r+1) ans=max(ans,r-l+1);
    else
    
        int st=l,j;
        for(j=0;j<pos[a[i]].size();j++)if(st<=pos[a[i]][j])break;
          for(;j<pos[a[i]].size()&&pos[a[i]][j]<r;j++)
          
              dfs(st,pos[a[i]][j]-1);
              st=pos[a[i]][j]+1;
          
          if(j<pos[a[i]].size())
                   dfs(st,r);
          else
          
              dfs(pos[a[i]][j-1]+1,r);
          

    
    return ;

int main()


    while(cin>>n>>c>>k)
    
         for(int i=1;i<=c;i++)pos[i].clear();
        met(a,0);
        ans=0;
        for(int i=1; i<=n; i++)
        
            scanf("%d",&a[i]);
            pos[a[i]].push_back(i);
        
        // cout<<"1"<<"        "<<n<<endl;
        dfs(1,n);

        cout<<ans<<endl;
    
    return 0;

 




 

以上是关于2019年杭电多校训练1012的主要内容,如果未能解决你的问题,请参考以下文章

2019年杭电多校第九场07题(HDU6686+树形dp)

2019年杭电多校第三场 1011题Squrirrel(HDU6613+树DP)

2019年杭电多校第二场 1008题Harmonious Army(HDU6598+最小割+建图)

2019年杭电多校第二场 1002题Beauty Of Unimodal Sequence(LIS+单调栈)

2022 年杭电多校第七场 1007 Weighted Beautiful Tree

2022 年杭电多校第七场 1007 Weighted Beautiful Tree