cf#348-E. Little Artem and Time Machine-树状数组+map节点(动态开点树状数组)

来源:互联网 发布:ps淘宝宝贝详情页尺寸 编辑:程序博客网 时间:2024/06/06 00:50

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;}


0 0