园丁的烦恼 树状数组 + 离散化 +排序
非常simple的二维数点问题。
1. 读入(这TM不是屁话)
2. 离散坐标(也是P话)
3. 按照从左到右,从下到上排序
4. 离线处理每一个矩阵,可以提前存好是加还是减,总之空间开4倍
5. 不要忘记开O2哟~
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
const int maxm=5000000+5;
const int maxn=5000000+2;
int x[maxm], y[maxm], idx[maxm],A[maxm];
int C[maxm], ans[maxm];
int X[maxm];
int cmp(int i,int j)
{
if(y[i]==y[j]){
if(x[i]==x[j])return abs(idx[i])<abs(idx[j]);
return x[i]<x[j];
}
return y[i]<y[j];
}
int lowbit(int t){return t&(-t);}
void update(int x,int delta)
{
while(x<maxn)C[x]+=delta,x+=lowbit(x);
}
int query(int x)
{
int tmp=0;
while(x>0)tmp+=C[x], x-=lowbit(x);
return tmp;
}
int main()
{
int n,m,cnt;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i){
scanf("%d%d",&x[i],&y[i]);
idx[i]=0;
++x[i];
X[i]=x[i];
++y[i];
}
cnt=n;
for(int i=1;i<=m;++i)
{
int a,b,c,d;
scanf("%d%d%d%d",&a,&b,&c,&d);
++a;++b;++c;++d; //真实坐标
++cnt;
x[cnt]=a-1, y[cnt]=b-1, idx[cnt]=1, X[cnt]=a-1;
++cnt;
x[cnt]=c, y[cnt]=b-1, idx[cnt]=-1, X[cnt]=c;
++cnt;
x[cnt]=a-1, y[cnt]=d, idx[cnt]=-1, X[cnt]=a-1;
++cnt;
x[cnt]=c, y[cnt]=d, idx[cnt]=1, X[cnt]=c;
}
sort(X+1,X+1+cnt);
for(int i=1;i<=cnt;++i){
A[i]=i;
x[i]=lower_bound(X+1,X+1+cnt,x[i])-X;
}
sort(A+1,A+1+cnt,cmp);
for(int i=1;i<=cnt;++i)
{
int cur=A[i];
if(idx[cur]==0)update(x[cur], 1);
else
{
int h=query(x[cur]);
ans[cur]=(idx[cur]*h);
}
}
for(int i=n+1;i<=cnt;i+=4)
{
int h=ans[i]+ans[i+1]+ans[i+2]+ans[i+3];
printf("%d\n",h);
}
return 0;
}