wqy的B题

wqy的B题

题意:

和一道叫机器翻译的题差不多,不过这道题要难一些,没有规定必须删除最早入队的。

解法:

解法和[POI2005]SAM-Toy Cars这道题差不多,考虑贪心。
每次选取下一次使用最远的点删除。
拿个堆维护一下就好了。

CODE:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>

using namespace std;

#define LL long long
#define N 200010

int n,k,a[N],nxt[N],last[N];
priority_queue<pair<int,int> > q,del;
bool vis[N];

int main() {
    scanf("%d%d",&n,&k);
    for(int i = 1 ; i <= n ; i++) {
        scanf("%d",&a[i]);
        nxt[last[a[i]]] = i;
        last[a[i]] = i;
    }
    for(int i = 1 ; i <= N ; i++) {
        if(last[i]) nxt[last[i]] = n+1;
    }
    int ans = 0,size = 0;
    for(int i = 1 ; i <= n ; i++) {
        if(vis[a[i]]) {
            del.push(make_pair(i,a[i]));
            q.push(make_pair(nxt[i],a[i]));
            continue;
        }
        ans++;
        if(size < k) {
            vis[a[i]] = 1;
            size++;
            q.push(make_pair(nxt[i],a[i]));
        } else {
            while(!q.empty() && !del.empty() && q.top() == del.top()) q.pop(),del.pop();
            int num = q.top().second;
            q.pop();
            vis[num] = 0;
            vis[a[i]] = 1;
            q.push(make_pair(nxt[i],a[i]));
        }
    }
    printf("%d \n",ans);
    //system("pause");
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/Repulser/p/11409392.html