Little Artem has invented a time machine! He could go anywhere in time, but all his thoughts of course are with computer science. He wants to apply this time machine to a well-known data structure: multiset.
Artem wants to create a basic multiset of integers. He wants these structure to support operations of three types:
But what about time machine? Artem doesn't simply apply operations to the multiset one by one, he now travels to different moments of time and apply his operation there. Consider the following example.
Note that Artem dislikes exceptions so much that he assures that after each change he makes all delete operations are applied only to element that is present in the multiset. The answer to the query of the third type is computed at the moment Artem makes the corresponding query and are not affected in any way by future changes he makes.
Help Artem implement time travellers multiset.
The first line of the input contains a single integer n (1 ≤ n ≤ 100 000) — the number of Artem's queries.
Then follow n lines with queries descriptions. Each of them contains three integers ai, ti and xi (1 ≤ ai ≤ 3, 1 ≤ ti, xi ≤ 109) — type of the query, moment of time Artem travels to in order to execute this query and the value of the query itself, respectively. It's guaranteed that all moments of time are distinct and that after each operation is applied all operations of the first and second types are consistent.
For each ask operation output the number of instances of integer being queried at the given moment of time.
6
1 1 5
3 5 5
1 2 5
3 6 5
2 3 5
3 7 5
1
2
1
3
1 1 1
2 2 1
3 3 1
0
题意:给你一个n,然后接下来执行n步,有三种选择,1表示增加一个值,2表示删除这个数的一个值,3表示查询
每一步的命令有op,time,num三个数,表示在time是对num这个数进行操作。(1<=n<=1e5,1<=time,num<=1e9)
思路:
方法一:由于是按顺序执行下来的,我们可以对时间进行离散化,然后用树状数组+map维护每一个位置的num的值。
时间复杂度n*logn*logn,空间n*logn
方法二:
对num也可以离散化,这样会使得时间复杂度变为nlogn,但是这样的话,空间是不够的,
所以我们对num不进行区分,把要修改的num一样的数放在一起操作,
先处理出所有对应的时间没有任何num这个数字时每个时间点的前缀和,
然后把后面的修改插入之后查询的答案,两者相减,就是这个位置的实际答案。
时间复杂度nlogn
方法一代码:
#include<bits/stdc++.h> using namespace std; const int maxn=101000; struct node{ int kind,time,val; }Q[maxn]; int t[maxn],cnt=0,n; map<int,int>C[maxn]; int HASH(int num){ return lower_bound(t+1,t+cnt+1,num)-t; } void add(int x,int val,int v){ while(x<=n){ C[x][val]+=v; x+=(x&-x); } } int sum(int x,int val){ int ret=0; while(x>0){ ret+=C[x][val]; x-=(x&-x); } return ret; } int main(){ scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d%d%d",&Q[i].kind,&Q[i].time,&Q[i].val); t[++cnt]=Q[i].time; } int cnt1=0; sort(t+1,t+cnt+1); cnt=unique(t+1,t+cnt+1)-t-1; for(int i=1;i<=n;i++){ int Num=HASH(Q[i].time); if(Q[i].kind==1) add(Num,Q[i].val,1); else if(Q[i].kind==2) add(Num,Q[i].val,-1); else printf("%d\n",sum(Num,Q[i].val)); } return 0; }