前言
一开始就有点歪,尺取法待补
传送门 :
思路
一开始以为是二分答案,二分左端点毕竟如果是二分金钱的话
时间复杂度( l o g n ∗ m ∗ n log_n*m*n logn∗m∗n) 感觉会超时
结果二分左端点没二分出来,实践证明没有单调性
所以又乖乖滚回去二分金钱,显然对于已有金钱,我们只需要判断左右两边是否有满足
答案的即可,所以我们直接按照这个模拟即可
CODE
#include <iostream>
#include <vector>
#include <map>
#include <unordered_map>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
#define ll long long
#define endl '\n'
typedef pair<int,int> pii;
unordered_map<int,int> mp;
const int N = 1e6+10;
int a[N];
int n,m,cnt;
int ansl,ansr ;
bool check(int x)
{
int cnt = 0 ;
mp.clear();
for(int i=1;i<=x;i++){
if(!mp[a[i]]) ++cnt;
mp[a[i]]++;
}
if(cnt == m)
{
ansl = 1,ansr = x;
return true;
}
int idx = 1;
for(int i = x+1;i<=n;i++)
{
mp[a[idx]] -- ;
if(!mp[a[idx]]) cnt -- ;
idx++;
mp[a[i]]++;
if(mp[a[i]] == 1 )cnt++;
if(cnt == m){
ansl = idx,ansr = i;
return true;
}
}
return false;
}
void solve()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
cin>>a[i];
int l = 1, r= n ;
// while(l+1<r)
// {
// int mid = l+r>>1;
// if(check(mid))
// r = mid;
// else
// l =mid;
// }
// cout<<ansl<<" "<<ansr<<endl;
while(l<=r)
{
int mid = l+r >> 1;
if(check(mid))
r = mid-1;
else
l = mid+1;
}
// cout<<l<<" "<<r<<endl;
cout<<ansl<<" "<<ansr<<endl;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
//int t;cin>>t;while(t -- )
solve();
return 0;
}