P2163 [SHOI2007] 园丁的烦恼 做题笔记
二维数点。
写得有点shi。
关于我数组开小爆炸这一件事:

写代码写着写着晕了。
#include<bits/stdc++.h>
#define endl '\n'
using namespace std;
const int maxn=1.5e6+10,V=1e6+10;//懒得改了,直接开大
int a[maxn],tot,tx,ty,tot2,ans[maxn];
struct tr{//园丁的树
int x,y,id;
friend bool operator<(tr aa,tr bb){
return aa.x<bb.x;
}
}v[maxn];
struct qry{
int a,b,c,d,id;
}b[maxn];
struct qry2{
int x,y,type,id;
friend bool operator<(qry2 aa,qry2 bb){
return aa.x<bb.x;
}
}q[maxn*4];
int bx[maxn],by[maxn];
int getx(int x){return lower_bound(bx+1,bx+tx+1,x)-bx;}
int gety(int y){return lower_bound(by+1,by+ty+1,y)-by;}
struct node{
int l,r,sum;
}t[maxn*4];
#define ls id<<1
#define rs id<<1|1
void up(int id){t[id].sum=t[ls].sum+t[rs].sum;}
void build(int id,int l,int r){
t[id].l=l,t[id].r=r;
if(l==r){
t[id].sum=0;//后面要逐个插入
return;
}
int mid=(l+r)>>1;
build(ls,l,mid);
build(rs,mid+1,r);
up(id);
}
void add(int id,int x){
if(t[id].r<x||t[id].l>x)return;
if(t[id].l==t[id].r&&t[id].l==x){
t[id].sum++;
return;
}
add(ls,x),add(rs,x);
up(id);
}
int query(int id,int l,int r){
if(t[id].r<l||t[id].l>r)return 0;
if(l<=t[id].l&&t[id].r<=r)return t[id].sum;
return query(ls,l,r)+query(rs,l,r);
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++){
int x,y;
cin>>x>>y;
v[i]={x,y,i};
bx[++tx]=x,by[++ty]=y;
}
for(int i=1;i<=m;i++){
int A,B,C,D;
cin>>A>>B>>C>>D;
b[++tot]={A,B,C,D,i};
bx[++tx]=A,bx[++tx]=C;
by[++ty]=B,by[++ty]=D;
}
sort(bx+1,bx+tx+1);
sort(by+1,by+ty+1);
tx=unique(bx+1,bx+tx+1)-bx-1;
ty=unique(by+1,by+ty+1)-by-1;
for(int i=1;i<=n;i++)v[i]={getx(v[i].x),gety(v[i].y),v[i].id};
for(int i=1;i<=m;i++)b[i]={getx(b[i].a),gety(b[i].b),getx(b[i].c),gety(b[i].d),b[i].id};
build(1,1,V);
int k=1;
sort(v+1,v+n+1);
for(int i=1;i<=n;i++)a[i]=v[i].y;
for(int i=1;i<=m;i++){
q[++tot2]={b[i].c,b[i].d,1,i};
q[++tot2]={b[i].a-1,b[i].b-1,1,i};
q[++tot2]={b[i].a-1,b[i].d,-1,i};
q[++tot2]={b[i].c,b[i].b-1,-1,i};
}
sort(q+1,q+tot2+1);
for(int i=1;i<=tot2;i++){
while(v[k].x<=q[i].x&&k<=n)add(1,a[k++]);
ans[q[i].id]+=q[i].type*query(1,1,q[i].y);
// cout<<q[i].type*query(1,1,q[i].r)<<endl;
}
for(int i=1;i<=m;i++)cout<<ans[i]<<endl;
return 0;
}

浙公网安备 33010602011771号