Codeforces Round #348 E. Little Artem and Time Machine(给你一个n,有三种选择,1表示增加一个值,2表示删除这个数的一个值,3表示查询)

E. Little Artem and Time Machine
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

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:

  1. Add integer to the multiset. Note that the difference between set and multiset is that multiset may store several instances of one integer.
  2. Remove integer from the multiset. Only one instance of this integer is removed. Artem doesn't want to handle any exceptions, so he assumes that every time remove operation is called, that integer is presented in the multiset.
  3. Count the number of instances of the given integer that are stored in the multiset.

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.

  • First Artem adds integer 5 to the multiset at the 1-st moment of time.
  • Then Artem adds integer 3 to the multiset at the moment 5.
  • Then Artem asks how many 5 are there in the multiset at moment 6. The answer is 1.
  • Then Artem returns back in time and asks how many integers 3 are there in the set at moment 4. Since 3 was added only at moment5, the number of integers 3 at moment 4 equals to 0.
  • Then Artem goes back in time again and removes 5 from the multiset at moment 3.
  • Finally Artyom asks at moment 7 how many integers 5 are there in the set. The result is 0, since we have removed 5 at the moment 3.

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.

Input

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 aiti and xi (1 ≤ ai ≤ 31 ≤ 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.

Output

For each ask operation output the number of instances of integer being queried at the given moment of time.

Examples
input
6
1 1 5
3 5 5
1 2 5
3 6 5
2 3 5
3 7 5
output
1
2
1
input
3
1 1 1
2 2 1
3 3 1
output
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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值