题意:
要你维护一个带时间戳的multiset,有三种操作。
- 形如:1 a b ,在第a秒插入1个b。
- 形如:2 a b ,在第a秒删除1个b。
- 形如:3 a b ,查询当前在a秒时有多少个b。
需要注意输入有顺序,multiset自己也有时间戳。
题解:
感觉CDQ可以做,2维的,写了一发然后AC了,第一次独立写CDQ。
我对CDQ理解也不深,不乱说了,直接看代码比较简单。
#include<bits/stdc++.h>
using namespace std;
const int N = +;
struct op{
int tp, sp, x, id;
op(){}
op(int a, int b, int c, int d) { tp = a, sp = b, x = c, id = d; }
bool operator < (const op& a) const{ return sp < a.sp; }
}qry[N];
map<int,int>st;
int ans[N] = {};
bool vis[N] = {};
int acnt = ;
inline bool cmp(const op& a, const op& b){
return a.id < b.id;
}
void CDQ(int l, int r){
if(l >= r) return;
int mid = (l+r) >> ;
CDQ(l, mid);
CDQ(mid+, r);
sort(qry+l, qry+r+);
for(int i = l; i <= r; ++i){
op& x = qry[i];
if(x.id <= mid){
if(x.tp == ) st[x.x] += ;
else if(x.tp == ) st[x.x] -= ;
}
else { if(x.tp == ) ans[x.id] += st[x.x]; }
}
for(int i = l; i <= r; ++i){
op& x = qry[i];
if(x.id <= mid){
if(x.tp == ) st[x.x] -= ;
else if(x.tp == ) st[x.x] += ;
}
}
sort(qry+l, qry+r+, cmp);
}
int main(){
int n;
scanf("%d", &n);
for(int i = ; i <= n; ++i){
scanf("%d%d%d", &qry[i].tp, &qry[i].sp, &qry[i].x);
qry[i].id = i;
if(qry[i].tp == ) vis[i] = ;
}
CDQ(, n);
for(int i = ; i <= n; ++i) if(vis[i]) printf("%d\n", ans[i]);
}