你有一个可以调节容量的(存放数字)容器,一开始为空。
给你N次查询 。问有至少多大的容量能完成K次完美操作。
如果这个数字不在容器,并且容器满了,那就将最久之前查询的数从容器种删除,再加上这个数。如果容器没满就直接加入。
如果在容器就将这次查询称为完美操作。
容器越大,完美操作数肯定越高。因为不会使别的数被删除。
所以容量具有单调性。
这样我们就可以二分枚举出这个答案了。log
这样我们需要在On内判断出枚举的答案的准确性。
我们利用哈希表和队列来模拟这个操作。
用哈希值来记录在不在容器里。
我们多次将这个值入队来保证权重,
而且在出队的时候一定要出队到真实值,即哈希值为1。
最多只会入队N次。
所以时间复杂度是可以的。
没开这题属实可惜。
#include <iostream> #include <cstdio> #include <cstring> #include <queue> #include <vector> #include <algorithm> #include <map> #include <string> #include <unordered_map> using namespace std; const int INF = 0x3f3f3f3f; int n , k ; int a[100100] ; bool che( int m ) { queue <int> q ; int re = 0 ,cnt = 0 ; unordered_map < int , int > mp ; for ( int i = 1 ; i <= n ; i++ ) { if ( mp[a[i]] != 0 ) { q.push(a[i]) ; mp[a[i]]++ ; re++ ; }else if ( cnt != m ) { q.push(a[i]) ; mp[a[i]] = 1 ; cnt++ ; }else { while ( cnt == m ) { int f = q.front(); q.pop(); mp[f]--; if ( mp[f] == 0 ) cnt--; } q.push(a[i]); mp[a[i]]++; cnt++; } } if ( re >= k ) return 1 ; else return 0 ; } int main () { ios::sync_with_stdio(false);cin.tie(0); cin >> n >> k ; for ( int i = 1 ; i <= n ; i++ ) { cin >> a[i] ; } int t1 = 1 , t2 = n ; while ( t1 < t2 ) { int mid = t1 + t2 >> 1 ; if ( che( mid ) ) { t2 = mid ; }else t1 = mid + 1 ; } if (che(t2)) cout << t2 << "\n" ; else cout << "cbddl\n" ; return 0 ; }