CodeForces - 669E Little Artem and Time Machine (cdq分治)

Little Artem and Time Machine

 CodeForces - 669E 

题目大意:有三种操作

1。在时间x位置y上+1;

2。在时间x位置y上-1;

3。查询时间x位置y上的值;

解题思路:对于每个查询我们将原来的问题转化为偏序问题,即对于每一个查询,我们需要统计输入顺序小于当前顺序&&时间小于当前x的y的值。即(输入顺序,时间,值);

输入顺序已经有序。题目保证时间不同。

ps:cdq里边套用sort会很麻,但是很方便,另一种处理方法是在cdq的过程中对x归并左右两边的序列来保证左右两边时间有序。

#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
#define LL long long
#define N 200005
#define inf 0x3f3f3f3f
#define sca(n) scanf("%d",&n)
#define pb(x) push_back(x)
struct node
{
    int op,x,y,id;
}p[N];

vector<int>V;
vector<int>V1;

bool cmp(node a,node b)
{
    return a.x<b.x;
}

int sum[N];
int ou[N];
void cdq(int l,int r)
{
    if(l==r)return ;
    int m=(l+r)>>1;
    cdq(l,m),cdq(m+1,r);
    sort(p+l,p+m+1,cmp );
    sort(p+1+m,p+r+1,cmp );
    int R=m+1;
    int L=l;
    for( ;R<=r;R++)
    {
        while(L<=m&&((p[L].x<p[R].x)||p[L].op==3))
        {
            if(p[L].op==1)sum[p[L].y]++;
            if(p[L].op==2)sum[p[L].y]--;
            L++;
        }
        if(p[R].op==3)ou[p[R].id]+=sum[p[R].y];
    }
    for(int i=l;i<L;i++)
    {
        if(p[i].op==1)sum[p[i].y]--;
        if(p[i].op==2)sum[p[i].y]++;
    }
}
int main()
{
    int n;
    scanf("%d",&n);
    int op,a,b;
    int id=0;
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d%d",&op,&a,&b);
        if(op==3)id++;
        p[i]=node{op,a,b,id};
        V.pb(b);
        V1.pb(a);
    }
    sort(V1.begin(),V1.end());
    sort(V.begin(),V.end());
    unique(V1.begin(),V1.end());
    unique(V.begin(),V.end());
    for(int i=1;i<=n;i++)
    {
        p[i].x=lower_bound(V1.begin(),V1.end(),p[i].x)-V1.begin();
        p[i].y=lower_bound(V.begin(),V.end(),p[i].y)-V.begin();
    }
    cdq(1,n);
    for(int i=1;i<=id;i++)printf("%d\n",ou[i]);
}

猜你喜欢

转载自blog.csdn.net/weixin_40894017/article/details/88555089