……啊開始頹了。c++
【題目大意】app
已知當前集合最大容量爲m,n個詢問。每次詢問一個元素,若是集合中沒有則須要加入該元素,若是集合已經滿了則須要先刪去集合中的某些元素再加入。問至少要加入幾回元素?spa
【思路】code
顯然每一次刪除的元素是下一次出現最晚的那一個,優先隊列維護一下就行了。blog
【錯誤點】隊列
很是ZZ地把集合滿的條件定爲了「que.size()==m」,實際上若是該元素已經存在,咱們更新下一次出現的時候原來的在優先隊列中是不刪除的。因此必須另外設一個qsize記錄集合中有幾個元素存在。hash
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int MAXN=110000; 4 typedef pair<int,int> p; 5 const int INF=0x7fffffff; 6 int n,m,a[MAXN],d,hash[MAXN]; 7 int rcap[MAXN],nap[MAXN];//recently appear & next appear 8 priority_queue<p> que; 9 int inque[MAXN],qsize; 10 11 void init() 12 { 13 scanf("%d%d",&n,&m); 14 for (int i=1;i<=n;i++) scanf("%d",&a[i]),hash[i]=a[i]; 15 sort(hash+1,hash+n+1); 16 d=unique(hash+1,hash+n+1)-(hash+1); 17 for (int i=1;i<=n;i++) a[i]=lower_bound(hash+1,hash+d+1,a[i])-hash; 18 for (int i=1;i<=n;i++) rcap[i]=nap[i]=INF; 19 for (int i=1;i<=n;i++) 20 { 21 if (rcap[a[i]]!=INF) nap[rcap[a[i]]]=i; 22 rcap[a[i]]=i; 23 } 24 } 25 26 void solve() 27 { 28 int ans=0; 29 memset(inque,0,sizeof(inque)); 30 qsize=0; 31 for (int i=1;i<=n;i++) 32 { 33 if (!inque[a[i]]) 34 { 35 if (qsize==m) //這裏不能用que.size()代替,由於相同元素可能都在優先隊列裏呢 36 { 37 inque[que.top().second]=0; 38 que.pop(); 39 qsize--; 40 } 41 inque[a[i]]=1; 42 ans++; 43 qsize++; 44 } 45 que.push(p(nap[i],a[i])); 46 } 47 printf("%d\n",ans); 48 } 49 50 int main() 51 { 52 init(); 53 solve(); 54 return 0; 55 }