最简单的穷举L,R然后区间里面求和看看是否满足条件(n^3)显然是过不了的。
对穷举L,R这一部分用尺取法优化一下就会喜提TL代码...(n^2)
TLE代码(54分)
#include <bits/stdc++.h>
using namespace std;
const int MAXN=1e6+1;
int n,m,a[MAXN],ansl=INT_MIN/2,ansr=INT_MAX/2,ans;
inline void scan(){
cin>>n>>m;
for(int i=1;i<=n;i++)
cin>>a[i];
}
bool isOK(int l,int r){
bitset<2001>vis;
int cnt=0;
for(int i=l;i<=r;i++){
if(!vis[a[i]]){
vis[a[i]]=true;
cnt++;
}
}
if(cnt>=m)return true;
return false;
}
int main(){
cin.tie(0),cout.tie(0);
ios::sync_with_stdio(false);
scan();
for(int l=1,r=1;r<=n;r++){
if(!isOK(l,r))continue;
while(isOK(l+1,r))l++;
if(r-l<ansr-ansl){
ansr=r;
ansl=l;
}
if(r-l==ansr-ansl&&l<ansl){
ansl=l;
ansr=r;
}
}
cout<<ansl<<" "<<ansr;
return 0;
}
很明显对于isOK判断函数可以简单的变成L,R两点的缩放。大常数(n)
AC代码
#include <bits/stdc++.h>
using namespace std;
const int MAXN=1e6+1;
int n,m,a[MAXN],ansl=INT_MIN/2,ansr=INT_MAX/2,ans,cnt;
int vis[2001];
inline void scan(){
cin>>n>>m;
for(int i=1;i<=n;i++)
cin>>a[i];
}
int main(){
cin.tie(0),cout.tie(0);
ios::sync_with_stdio(false);
scan();
for(int l=1,r=1;r<=n;r++){
if(!vis[a[r]]){
cnt++;
}vis[a[r]]++;
if(cnt<m)continue;
while(cnt>=m&&vis[a[l]]>1){
vis[a[l]]--;
l++;
}
if(r-l<ansr-ansl){
ansr=r;
ansl=l;
}
if(r-l==ansr-ansl&&l<ansl){
ansl=l;
ansr=r;
}
}
cout<<ansl<<" "<<ansr;
return 0;
}