Little Artem and Time Machine
题目大意:有三种操作
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]);
}