CodeForces - 802B Heidi and Library (medium)
阿新 • • 發佈:2017-08-02
不用 rar cout while eas medium data 保持 con
Input
Whereas humans nowadays read fewer and fewer books on paper, book readership among marmots has surged. Heidi has expanded the library and is now serving longer request sequences.
Input
Same as the easy version, but the limits have changed: 1?≤?n,?k?≤?400?000.
Output
Same as the easy version.
Example
4 100Output
1 2 2 1
2Input
4 1Output
1 2 2 1
3Input
4 2Output
1 2 3 1
3
題目大意:
有n條用戶需要的書,圖書館最多只能有k本書,如果用戶需要第i本書,圖書館沒有第i本書,那麽就需要購買第i本書,如果這時候圖書館的書多於k本,
那麽需要扔掉一本書,以保持圖書數量在k本以內,一開始圖書館一本書也沒有,問最少需要購買多少次書,以滿足所有需求。
分析:
貪心,當需要扔書時,優先扔後面已經不需要的書,當後面沒有不需要的書的時候,優先扔需要被用到的時間最晚的書。
比如:
6 2
1 2 3 4 2 1
就是先買1 2兩本書,買第三本書3時優先扔1,因為1用到的時候最晚,總不能這一次扔了2,馬上就要把2買回來。。。。。。
然後買4的時候扔3,因為後面3已經不需要再被用到了,然後2已經有了不用再買了,之後再買一次1,(4和2隨便扔一本)就結束了。
總共需要購買5次
實現方法:
用優先隊列去實現,取下一次每本書第一次出現的時間中最晚的哪一本,如果這本書已經不需要再買,設置其值為INF,即出現的時間無限晚。
一本書的指針值更新之後,優先隊列中某些元素就會失效,所以元素出隊的時候要比較一下,隊列出去的元素是否和儲存的值相同,如果不同,
棄掉重取,直至有用為止。
代碼:
#include<iostream> using namespace std; #include<queue> #include<cstdio> #include<map> #include<queue> #include<vector> int cs = 0; typedef long long LL; int n, k; int fs[4001000];//記錄下一次出現的時間 struct data { int sj; int bh; bool operator<(const data &b)const { return this->sj<b.sj; } }; int a[500000]; bool v[500000]; vector<int> ne[500000];//記錄每本書依次出現的時間 int zz[500000];//一個指向每本書出現的次數的指針 priority_queue<struct data> team; int main() { cin >> n >> k; for (int i = 1; i <= n; i++) { scanf("%d", &a[i]); ne[a[i]].push_back(i); fs[a[i]] = i; } int ans = 0; cs = 0; for (int i = 1; i <= n; i++) { //如果存在更新其隊列中的值 if (v[a[i]]) { struct data pd; pd.bh = a[i]; zz[a[i]]++; if (zz[a[i]] + 1>ne[a[i]].size()) fs[a[i]] = 0x7fffffff; else fs[a[i]] = ne[a[i]][zz[a[i]]]; pd.sj = fs[a[i]]; team.push(pd); continue; } ans += 1; cs += 1; v[a[i]] = 1; if (cs>k) { /*取隊列中,與記錄出現時間相符的有效值,扔掉時間不相同的無用值*/ struct data pt = team.top(); while (pt.sj != fs[pt.bh]) { team.pop(); if (team.empty()) break; pt = team.top(); } team.pop(); v[pt.bh] = 0; } //買一本新書後更新其值 struct data pd; pd.bh = a[i]; zz[a[i]]++; //zz指針大於這種書出現過的次數,即這本書不會再出現 if (zz[a[i]] + 1>ne[a[i]].size()) fs[a[i]] = 0x7fffffff; else fs[a[i]] = ne[a[i]][zz[a[i]]]; pd.sj = fs[a[i]]; team.push(pd); } cout << ans << endl; return 0; }
CodeForces - 802B Heidi and Library (medium)