[CF# 366 Thor] STL模拟
题目链接:
[CF# 366 Thor]
题意描述:N 种物品标号为1~N, Q次操作:
- 标号为x 的物品增加一个;
- 将标号为x的物品全部删除;
- 将最初加入的前t次物品全部删除。
解题思路:想了好久,就是想不到模拟。 竟然一直想着用树状数组求和....
直接看官方题解吧....
Consider a queue e for every application and also a queue Q for the notification bar. When an event of the first type happens, increase the number of unread notifications by 1 and push pair (i, x) to Q where i is the index of this event among events of the first type, and also push number i to queue e[x].
When a second type event happens, mark all numbers in queue e[x] and clear this queue (also decreese the number of unread notifications by the number of elements in this queue before clearing).
When a third type query happens, do the following:
while Q is not empty and Q.front().first <= t:
i = Q.front().first
x = Q.front().second
Q.pop()
if mark[i] is false:
mark[i] = true
e[v].pop()
ans = ans - 1 // it always contains the number of unread notifications
But in C++ set works much faster than queue!
Time Complexity:
#include <cmath>
#include <queue>
#include <vector>
#include <cstdio>
#include <string>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <algorithm>
using namespace std;
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#define FIN freopen("input.txt","r",stdin)
#define FOUT freopen("output.txt","w",stdout)
#define fst first
#define snd second
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
typedef __int64 LL;
//typedef long long LL;
typedef unsigned int uint;
typedef pair<int, int> PII;
const int MAXN = 300000 + 5;
int N, Q_CNT;
int type, res;
priority_queue<PII, vector<PII>, greater<PII> > Q;
queue<int> E[MAXN];
bool vis[MAXN];
int main() {
#ifndef ONLINE_JUDGE
FIN;
#endif // ONLINE_JUDGE
int x, t, id;
PII top;
while (~scanf ("%d %d", &N, &Q_CNT) ) {
res = id = 0;
while (!Q.empty() ) Q.pop();
for (int i = 1; i <= N; i++) while (!E[i].empty() ) E[i].pop();
memset (vis, false, sizeof (vis) );
for (int i = 1; i <= Q_CNT; i ++) {
scanf ("%d", &type);
if (type == 1) {
scanf ("%d", &x);
++ id;
Q.push (PII (id, x) );
E[x].push (id);
++ res;
} else if (type == 2) {
scanf ("%d", &x);
while (!E[x].empty() ) {
t = E[x].front();
E[x].pop();
if (!vis[t]) {
vis[t] = true;
-- res;
}
}
} else {
scanf ("%d", &t);
while (!Q.empty() ) {
top = Q.top();
if (top.fst > t) break;
if (!vis[top.fst]) {
vis[top.fst] = true;
-- res;
}
Q.pop();
}
}
printf ("%d\n", res);
}
}
return 0;
}