2 solutions
-
1
难得能比较简短地写出来一个T3,发现已有题解用链表做的,我是用堆做的,于是简单分享一下。
大体思路还是模拟,关于如何定位是否存在某个编号的内存块,我选择用一个
set
,将关键字设置为块编号,用内置lower_bound
来实现。还有一点是需要找最近最久未使用,即时间戳最小的一个块,这里还是用一个set
,但是这两个set
关键字不同,于是乎我开了两个set
来解决这个问题()每次修改同时维护即可。(鄙人陋习,写cp代码不空格)
#include<bits/stdc++.h> using namespace std; const int maxn=(1<<16)+10; struct Node1{ int id,ti; bool ch; bool operator < (const Node1 &rhs) const { return id==rhs.id?ti<rhs.ti:id<rhs.id; } }; struct Node2{ int id,ti; bool ch; bool operator < (const Node2 &rhs) const { return ti==rhs.ti?id<rhs.id:ti<rhs.ti; } }; int n,N,m,cnt; set<Node1> s1[maxn]; set<Node2> s2[maxn]; int main() { scanf("%d%d%d",&n,&N,&m); while(m--) { int opt,x;scanf("%d%d",&opt,&x); int id=x%(n*N)/n;x++; auto it1=s1[id].lower_bound({x,0,0}); if(it1!=s1[id].end()&&(it1->id)==x) { Node1 u=*it1; s1[id].erase(it1); s1[id].insert({x,++cnt,u.ch||opt}); auto it2=s2[id].lower_bound({0,u.ti,0}); s2[id].erase(it2); s2[id].insert({x,cnt,u.ch||opt}); continue; } if((int)s2[id].size()<n) { // printf("==="); printf("0 %d\n",x-1); s1[id].insert({x,++cnt,(bool)opt}); s2[id].insert({x,cnt,(bool)opt}); } else { auto it2=s2[id].begin(); Node2 u=*s2[id].begin(); if(u.ch) { // printf("==="); printf("1 %d\n",u.id-1); } // printf("==="); printf("0 %d\n",x-1); it1=s1[id].lower_bound({u.id,0,0}); s1[id].erase(it1); s1[id].insert({x,++cnt,(bool)opt}); s2[id].erase(it2); s2[id].insert({x,cnt,(bool)opt}); } } return 0; }
Information
- ID
- 42
- Time
- 1000ms
- Memory
- 512MiB
- Difficulty
- 3
- Tags
- # Submissions
- 45
- Accepted
- 6
- Uploaded By