bzoj 1935: [Shoi2007]Tree 园丁的烦恼 离线+树状数组

来源:互联网 发布:爱之谷源码 编辑:程序博客网 时间:2024/05/18 03:15

题意

给定平面上的n个点(xi,yi),每次询问一个矩形内有多少个点。
n,m<=500000

分析

把一个询问拆成四个矩形,然后按x坐标排序后用树状数组维护即可。

代码

#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>using namespace std;const int N=2500005;int n,m,tot,w1,w[N],c[N],ans[500005];struct data{int op,x,y,id,val;}q[N];int read(){    int x=0,f=1;char ch=getchar();    while (ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}    while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}    return x*f;}bool cmp(data a,data b){    return a.x<b.x||a.x==b.x&&a.op<b.op;}void ins(int x,int y){    while (x<=w1) c[x]+=y,x+=x&(-x);}int query(int x){    int ans=0;    while (x) ans+=c[x],x-=x&(-x);    return ans;}int main(){    n=read();m=read();    for (int i=1;i<=n;i++) q[++tot].x=read(),q[tot].y=read(),q[tot].op=0,w[++w1]=q[i].y;    for (int i=1;i<=m;i++)    {        int x1=read(),y1=read(),x2=read(),y2=read();        q[++tot].x=x1-1;q[tot].y=y1-1;q[tot].op=1;q[tot].id=i;q[tot].val=1;w[++w1]=q[tot].y;        q[++tot].x=x2;q[tot].y=y1-1;q[tot].op=1;q[tot].id=i;q[tot].val=-1;w[++w1]=q[tot].y;        q[++tot].x=x1-1;q[tot].y=y2;q[tot].op=1;q[tot].id=i;q[tot].val=-1;w[++w1]=q[tot].y;        q[++tot].x=x2;q[tot].y=y2;q[tot].op=1;q[tot].id=i;q[tot].val=1;w[++w1]=q[tot].y;    }    sort(w+1,w+w1+1);w1=unique(w+1,w+w1+1)-w-1;    for (int i=1;i<=tot;i++) q[i].y=lower_bound(w+1,w+w1+1,q[i].y)-w;    sort(q+1,q+tot+1,cmp);    for (int i=1;i<=tot;i++)        if (q[i].op==0) ins(q[i].y,1);        else ans[q[i].id]+=q[i].val*query(q[i].y);    for (int i=1;i<=m;i++) printf("%d\n",ans[i]);    return 0;}
阅读全文
0 0