SCUT

https://scut.online/p/243

这道题唯一难点在于如何快速确定m合法。可以统计滑动窗口中已有元素的数量。

#include<bits/stdc++.h>
using namespace std;
#define ll long long

int n;
int a[100005];

int suma[100005];
int sum;

int cnta[100005];
int cntsum;

bool ok(int m){
    memset(cnta,0,sizeof(cnta));
    cntsum=0;

    for(int i=0;i<m;i++){
        if(cnta[a[i]]==0){
            cntsum++;
        }
        cnta[a[i]]++;
    }

    if(cntsum==sum){
        //m ok
        return 1;
    }

    for(int i=m;i<n;i++){
        {
            cnta[a[i-m]]--;
            if(cnta[a[i-m]]==0)
                cntsum--;
            if(cnta[a[i]]==0)
                cntsum++;
            cnta[a[i]]++;
        }
        if(cntsum==sum){
            //m ok
            return 1;
        }
    }

    return 0;
}

int main(){

    while(~scanf("%d",&n)){
        sum=0;
        memset(suma,0,sizeof(suma));
        for(int i=0;i<n;i++){
            scanf("%d",&a[i]);
            if(suma[a[i]]==0){
                sum++;
            }
            suma[a[i]]++;
        }

        //printf("sum=%d
",sum);

        int l=1,r=n,m;

        int res=0;
        while(l<=r){
            m=(l+r)/2;
            //cout<<m<<endl;
            if(m==l){
                if(ok(m)){
                    res=l;
                }
                else{
                    res=r;
                }
                break;
            }
            if(ok(m))
                r=m;
            else
                l=m+1;
        }

        printf("%d
",res);
    }
}
原文地址:https://www.cnblogs.com/Yinku/p/10403178.html