CodeForces 669E Little Artem and Time Machine

树状数组,$map$。

可以理解为开一个数组$f[i][j]$记录:$i$这个数字在时间$j$的操作情况。

操作$1$:$f[x][t]++$。操作$2$:$f[x][t]--$。操作$3$:$f[x][1]$至$f[x][t]$求和。

数组开不出来,但可以开$map$,状态最多$100000$个,所以还是不会超时的,数字范围有点大,可以离散化一下。

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<iostream>
using namespace std;
typedef long long LL;
const double pi=acos(-1.0),eps=1e-6;
void File()
{
    freopen("D:\in.txt","r",stdin);
    freopen("D:\out.txt","w",stdout);
}
template <class T>
inline void read(T &x)
{
    char c=getchar(); x=0;
    while(!isdigit(c)) c=getchar();
    while(isdigit(c)) {x=x*10+c-'0'; c=getchar();}
}

const int maxn=200010;
int n,op[maxn],t[maxn],x[maxn];
map<int,int>c[maxn];
int T[maxn],X[maxn];

int lowbit(int x){ return x&(-x); }

void update(int p,int q,int v)
{
    for(int i=q;i<=n;i=i+lowbit(i))
        c[p][i]+=v;
}

int sum(int p,int q)
{
    int res=0;
    for(int i=q;i>0;i=i-lowbit(i))
        res+=c[p][i];
    return res;
}

int get(int x)
{
    int L=1,R=n,pos;
    while(L<=R)
    {
        int m=(L+R)/2;
        if(X[m]>x) R=m-1;
        else if(X[m]<x) L=m+1;
        else pos=m,R=m-1;
    }
    return pos;
}

int g(int x)
{
    int L=1,R=n,pos;
    while(L<=R)
    {
        int m=(L+R)/2;
        if(T[m]>x) R=m-1;
        else if(T[m]<x) L=m+1;
        else pos=m,R=m-1;
    }
    return pos;
}

int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d%d",&op[i],&t[i],&x[i]);
        T[i]=t[i]; X[i]=x[i];
    }
    sort(T+1,T+1+n); sort(X+1,X+1+n);
    for(int i=1;i<=n;i++)
    {
        if(op[i]==1) update(get(x[i]),g(t[i]),1);
        else if(op[i]==2) update(get(x[i]),g(t[i]),-1);
        else printf("%d
",sum(get(x[i]),g(t[i])));
    }
    return 0;
}
原文地址:https://www.cnblogs.com/zufezzt/p/5909659.html