bzoj1935: [Shoi2007]Tree 园丁的烦恼

这题本来是想用二维树状数组水的。然后不会动态开数组,所以顺便补了一发cdq。

第一维时间,第二维x,第三维y,(其实我自己的感觉是第一维可以不要的),xy很大so离散化谢谢。

询问拆成4个。大家都懂。

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

int n,m;
struct node
{
    int x,y,tp;
}c[4100000];int clen;
void ins(int x,int y,int tp)
{
    clen++;
    c[clen].x=x;c[clen].y=y;c[clen].tp=tp;
}
int ls[8100000],lslen;
void LSH()
{
    lslen=0;
    for(int i=1;i<=clen;i++)
    {
        ls[++lslen]=c[i].x;
        ls[++lslen]=c[i].y;
    }
    sort(ls+1,ls+lslen+1);
    lslen=unique(ls+1,ls+1+lslen)-ls-1;
    for(int i=1;i<=clen;i++)
    {
        c[i].x=lower_bound(ls+1,ls+lslen+1,c[i].x)-ls;
        c[i].y=lower_bound(ls+1,ls+lslen+1,c[i].y)-ls;
    }
}


int s[4100000];
int lowbit(int x){return x&-x;}
void change(int x,int k)
{
    while(x<=lslen)
    {
        s[x]+=k;
        x+=lowbit(x);
    }
}
int getsum(int x)
{
    int ret=0;
    while(x>=1)
    {
        ret+=s[x];
        x-=lowbit(x);
    }
    return ret;
}

int as[510000];
node tt[4100000];
void cdq(int l,int r)
{
    if(l==r)return ;
    int mid=(l+r)/2;
    cdq(l,mid);cdq(mid+1,r);
    
    int i=l,j=mid+1,p=l;
    while(i<=mid&&j<=r)
    {
        if(c[i].x<c[j].x||(c[i].x==c[j].x&&abs(c[i].tp)<abs(c[j].tp)))
        {
            if(c[i].tp==0)change(c[i].y,1);
            tt[p++]=c[i++];
        }
        else
        {
            if(c[j].tp!=0)
            {
                if(c[j].tp>0)as[c[j].tp]+=getsum(c[j].y);
                else          as[-c[j].tp]-=getsum(c[j].y);
            }
            tt[p++]=c[j++];
        }
    }
    while(i<=mid)
    {
        if(c[i].tp==0)change(c[i].y,1);
        tt[p++]=c[i++];
    }
    while(j<=r)
    {
        if(c[j].tp!=0)
        {
            if(c[j].tp>0)as[c[j].tp]+=getsum(c[j].y);
            else          as[-c[j].tp]-=getsum(c[j].y);
        }
        tt[p++]=c[j++];
    }
    
    for(int i=l;i<=mid;i++)
        if(c[i].tp==0)change(c[i].y,-1);
    
    for(int i=l;i<=r;i++)c[i]=tt[i];
}
int main()
{
    scanf("%d%d",&n,&m);
    int x,y;clen=0;
    for(int i=1;i<=n;i++)
        scanf("%d%d",&x,&y), ins(x+1,y+1,0);
        
    int sx,sy,bx,by;
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d%d%d",&sx,&sy,&bx,&by);
        sx++;sy++;bx++;by++;
        ins(bx,by,i);
        ins(sx-1,by,-i);
        ins(bx,sy-1,-i);
        ins(sx-1,sy-1,i);
    }
    LSH();
    cdq(1,clen);
    
    for(int i=1;i<=m;i++)printf("%d\n",as[i]);
    return 0;
}

 

posted @ 2018-03-20 20:54  AKCqhzdy  阅读(163)  评论(1编辑  收藏  举报