http://codeforces.com/contest/669/problem/E
题意:
题意:有三个操作
1 x y,在第x秒插入一个y
2 x y,在第x秒移走一个y
3 x y, 问第x秒有多少个y
这个操作3可以问之前的时间,也可以问未来的时间。。。不太好离线搞
直接对数值y离散化,对于每个y建一个线段树/树状数组,维护的是时间这个维度,代表某段时间里,这个y值的出现情况
例如在x秒插入一个 y,相当于在y的树状数组里,x这个下标+1。
查询x秒时y的数量,就是相当于在y的树状数组里,【1,x】的和是什么。
这里对于每个值的树状数组不可能真的开一个 1e9的 管辖区间,因为总的访问量只有q,我们采用动态开点的方式即可,这里为了实现方便直接用map替代,缺点是时间复杂度多了一个log,对于本题还算可以接受
时间是q*log1e9*log(玄学),第一个log是树状数组的,第二个是map的(不会算)
代码:
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <iostream>
using namespace std;
const double pi=acos(-1.0);
double eps=0.000001;
typedef long long ll;
struct node
{
int x,y,z;
};
node tt[100005];
int bb[100005];
int idx[100005];
map<int ,int> tree[100050];
struct TREE
{
int lowbit(int x)
{
return x&-x;
}
void add(int x,int value,int id)
{
for (int i=x; i<=1e9; i=i+lowbit(i))
{
tree[id][i]+=value;
}
}
int get(int x,int id)
{
int sum=0;
for (int i=x; i; i-=lowbit(i))
{
sum+=tree[id][i];
}
return sum;
}
};
TREE tp[100005];
int main()
{
int q;
cin>>q;
int x,y,z;
for (int i=1; i<=q; i++)
{
scanf("%d%d%d",&x,&y,&z);
tt[i].x=x,tt[i].y=y,tt[i].z=z;
bb[i]=z;
}
sort(bb+1,bb+1+q);
int cun=unique(bb+1,bb+1+q)-bb-1;
for (int i=1; i<=q; i++)
idx[i]=lower_bound(bb+1,bb+1+cun,tt[i].z)-bb;
for (int i=1; i<=q; i++)
{
int x=tt[i].x,y=tt[i].y;
if (x==1)
tp[idx[i]].add(y,1,idx[i]);
if (x==2 )
tp[idx[i]].add(y,-1,idx[i]);
if (x==3)
{
int ret=tp[idx[i]].get(y,idx[i]);
printf("%d\n",ret);
}
}
return 0;
}