P2163 [SHOI2007]园丁的烦恼

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;

const int N=3e6+5;
const int M=1e7+5;

inline int read()
{
    char c=getchar();int num=0;
    for(;!isdigit(c);c=getchar());
    for(;isdigit(c);c=getchar())
        num=num*10+c-'0';
    return num;
}

struct QUE
{
    int x,y,f,id;
    bool operator < (const QUE &A) const
    {
        return x==A.x?(y==A.y?id<A.id:y<A.y):x<A.x;
    }
}tree[N];

int n,m,cnt;
int bound;

int bit[M];

inline void add(int x)
{
    for(;x<=bound;x+=x&(-x))
        ++bit[x];
}

inline int query(int x)
{
    int res=0;
    for(;x;x-=x&(-x))
        res+=bit[x];
    return res;
}

int ans[N];
int main()
{
    n=read(),m=read();
    for(int i=1;i<=n;++i)
    {
        tree[i].x=read(),++++tree[i].x,    //树状数组下标不能从0开始,因为0的二进制上没有1,会死循环,所以让左标++ 
        tree[i].y=read(),++++tree[i].y;
        bound=max(bound,tree[i].y);
    }
    cnt=n;
    for(int i=1,a,b,c,d;i<=m;++i)
    {
        a=read(),b=read(),c=read(),d=read();
        ++a,++b,++++c,++++d;    //a和b不用加,因为二维前缀和要-query(a+1-1)=query(a) 
        tree[++cnt].x=a,tree[cnt].y=b,tree[cnt].f=1,tree[cnt].id=i;        //二维前缀和 左上角 
        tree[++cnt].x=a,tree[cnt].y=d,tree[cnt].f=-1,tree[cnt].id=i;    //左下角 
        tree[++cnt].x=c,tree[cnt].y=b,tree[cnt].f=-1,tree[cnt].id=i;    //右上角 
        tree[++cnt].x=c,tree[cnt].y=d,tree[cnt].f=1,tree[cnt].id=i;        //右下角 
    }
    sort(tree+1,tree+cnt+1);
    for(int i=1;i<=cnt;++i)
    {
        if(!tree[i].id)        //插入 
            add(tree[i].y);
        else        //查询 
            ans[tree[i].id]+=query(tree[i].y)*tree[i].f;
    }
    for(int i=1;i<=m;++i)
        printf("%d\n",ans[i]);
    return 0;
}

 

posted @ 2018-09-12 11:40  whymhe  阅读(187)  评论(0编辑  收藏  举报