链接: http://codeforces.com/problemset/problem/669/E
思路: 以操作顺序和时间的二维偏序关系,对于每个op3 ,我们要求要更新的点其实是 id<nowid && time<nowtime。所以直接cdq。就可以了。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N =100005;
int num[N];
int tot;
struct node
{
int id;
int op;
int tim;
int x;
int flag;
}a[N];
int n;
int C[N];
int ans[N];
bool cmp(node a,node b)
{
if(a.tim==b.tim) return a.id<b.id;
return a.tim<b.tim;
}
bool cmp1(node a,node b)
{
return a.id<b.id;
};
void cdq(int l,int r)
{
if(l>=r) return ;
int mid=(l+r)>>1;
cdq(l,mid); cdq(mid+1,r);
for(int i=l;i<=r;i++)
{
if(a[i].id<=mid) a[i].flag=0;
else a[i].flag=1;
}
sort(a+l,a+r+1,cmp);
int tmpx;
for(int i=l;i<=r;i++)
{
if(a[i].flag==0)
{
if(a[i].op==1)
{
tmpx=a[i].x;
C[tmpx]++;
}
else if(a[i].op==2)
{
tmpx=a[i].x;
C[tmpx]--;
}
}
else
{
if(a[i].op==3)
{
tmpx=a[i].x;
//printf("*** %d %d\n",a[i].id,C[tmpx]);
ans[a[i].id]+=C[tmpx];
}
}
}
for(int i=l;i<=r;i++)
{
if(a[i].flag==0)
{
if(a[i].op==1)
{
tmpx=a[i].x;
C[tmpx]--;
}
else if(a[i].op==2)
{
tmpx=a[i].x;
C[tmpx]++;
}
}
}
}
int main()
{
scanf("%d",&n);
tot=0;
for(int i=1;i<=n;i++)
{
scanf("%d %d %d",&a[i].op,&a[i].tim, &a[i].x);
num[++tot]=a[i].x;
a[i].id=i;
}
sort(num+1,num+tot+1);
for(int i=1;i<=n;i++)
{
int in=lower_bound(num+1,num+tot+1,a[i].x)-num;
a[i].x=in;
}
cdq(1,n);
sort(a+1,a+n+1,cmp1);
for(int i=1;i<=n;i++)
{
if(a[i].op==3)
{
//printf("*** %d ",i);
printf("%d\n",ans[i]);
}
}
return 0;
}
/*
6
1 1 5
3 5 5
1 2 5
3 6 5
2 4 5
3 3 5
*/