zoukankan      html  css  js  c++  java
  • BZOJ1935 园丁的烦恼

    一个二维偏序的问题,学过了三维偏序cdq分治之后觉得这个题非常的水。只需按一维排序之后再用树状数组操作即可。——by VANE

    #include<bits/stdc++.h>
    using namespace std;
    const int N=5e5+5;
    struct qry
    {
        int x,y,id;
    }q[N<<2];
    struct tree
    {
        int x,y;
    }t[N];
    int s[N*5],n,m,tmp[N*5],num,vis_tim,ans[N*5];
    bool cmp(qry a,qry b)
    {
        return a.x<b.x;
    }
    bool cmpp(tree a,tree b)
    {
        return a.x<b.x;
    }
    void add(int x)
    {
        for(;x<=num;x+=x&-x)
            s[x]++;
    }
    int query(int x)
    {
        int res=0;
        for(;x;x-=x&-x)
            res+=s[x];
        return res;
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;++i)
            scanf("%d%d",&t[i].x,&t[i].y);
        for(int i=1;i<=m;++i)
        {
            int x,y,xx,yy;scanf("%d%d%d%d",&x,&y,&xx,&yy);
            int pos=(i-1)*4;
            q[pos+1].x=xx;q[pos+1].y=yy;q[pos+1].id=pos+1;
            q[pos+2].x=x-1;q[pos+2].y=y-1;q[pos+2].id=pos+2;
            q[pos+3].x=xx;q[pos+3].y=y-1;q[pos+3].id=pos+3;
            q[pos+4].x=x-1;q[pos+4].y=yy;q[pos+4].id=pos+4;
        }
        for(int i=1;i<=n;++i)
        tmp[i]=t[i].y;
        for(int i=1;i<=m*4;++i)
        tmp[i+n]=q[i].y;
        sort(tmp+1,tmp+1+n+m*4);
        num=unique(tmp+1,tmp+1+n+4*m)-tmp-1;
        for(int i=1;i<=n;++i) t[i].y=lower_bound(tmp+1,tmp+1+num,t[i].y)-tmp;
        for(int i=1;i<=m*4;++i) q[i].y=lower_bound(tmp+1,tmp+1+num,q[i].y)-tmp;
        sort(q+1,q+1+4*m,cmp);
        sort(t+1,t+1+n,cmpp);
        int i=1,j=1;
        while(j<=4*m)
        {
            int h=q[j].x;
            while(t[i].x<=h&&i<=n) add(t[i].y),++i;
            while(j<=4*m&&q[j].x==h)
            {
                ans[q[j].id]+=query(q[j].y);
                ++j;
            }
        }
        for(int i=1;i<=4*m;i+=4)
            printf("%d
    ",ans[i]+ans[i+1]-ans[i+2]-ans[i+3]);
    }

     二维偏序用cdq我是不是有病,我就是要写cdq 15000ms卡过去了

    By:大奕哥

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 struct node
     4 {
     5     int x,y,w,id,f;
     6     bool operator <(const node &b)const
     7     {
     8         return x==b.x?y<b.y:x<b.x;
     9     }
    10 }q[2500005];
    11 int cnt,maxr,tim;
    12 int t[10000005],v[10000005],ans[2500005],pos[500005];
    13 inline int lowbit(int x){return x&(-x);}
    14 void add(int x,int w)
    15 {
    16     for(;x<=maxr;x+=lowbit(x))
    17     {
    18         if(v[x]!=tim)
    19         {
    20             v[x]=tim;t[x]=w;
    21         }
    22         else t[x]+=w;
    23     }
    24 }
    25 int query(int x)
    26 {
    27     int an=0;
    28     for(;x;x-=lowbit(x))
    29     if(v[x]==tim)
    30     an+=t[x];
    31     return an;
    32 }
    33 void cdq(int l,int r)
    34 {
    35     if(l==r)return;
    36     int mid=(l+r)>>1;
    37     cdq(l,mid);cdq(mid+1,r);
    38     sort(q+l,q+mid+1);sort(q+mid+1,q+r+1);
    39     tim++;
    40     int i=l,j=mid+1;
    41     while(j<=r)
    42     {
    43         while(q[i].f==2&&i<=mid)++i;
    44         while(q[j].f==1&&j<=r)++j;
    45         if(q[i].x<=q[j].x&&i<=mid)add(q[i].y,q[i].w),++i;
    46         else if(j<=r)ans[q[j].id]+=query(q[j].y),++j;
    47     }
    48 }
    49 int main()
    50 {
    51     int n,m;
    52     scanf("%d%d",&n,&m);
    53     for(int i=1;i<=n;++i)
    54     {
    55         int x,y;
    56         scanf("%d%d",&x,&y);x++;y++;
    57         q[++cnt].f=1;q[cnt].x=x;q[cnt].y=y;q[cnt].w=1;q[cnt].id=cnt;maxr=max(maxr,y);
    58     }
    59     for(int i=1;i<=m;++i)
    60     {
    61         int x1,x2,y1,y2;
    62         scanf("%d%d%d%d",&x1,&y1,&x2,&y2);x1++;x2++;y1++;y2++;
    63         pos[i]=cnt;maxr=max(maxr,max(y1,y2));
    64         q[++cnt].f=2;q[cnt].x=x2;q[cnt].y=y2;q[cnt].id=cnt;
    65         q[++cnt].f=2;q[cnt].x=x1-1;q[cnt].y=y1-1;q[cnt].id=cnt;
    66         q[++cnt].f=2;q[cnt].x=x1-1;q[cnt].y=y2;q[cnt].id=cnt;
    67         q[++cnt].f=2;q[cnt].x=x2;q[cnt].y=y1-1;q[cnt].id=cnt;        
    68     }
    69     cdq(1,cnt);
    70     for(int i=1;i<=m;++i)
    71     printf("%d
    ",ans[pos[i]+1]+ans[pos[i]+2]-ans[pos[i]+3]-ans[pos[i]+4]);
    72     return 0;
    73 }
  • 相关阅读:
    给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。
    11
    实战 迁移学习 VGG19、ResNet50、InceptionV3 实践 猫狗大战 问题
    tx2系统备份与恢复
    如何在Ubuntu 18.04上安装和卸载TeamViewer
    bzoj 3732 Network (kruskal重构树)
    bzoj2152 聪聪可可 (树形dp)
    牛客 216D 消消乐 (二分图最小点覆盖)
    牛客 197E 01串
    Wannafly挑战赛23
  • 原文地址:https://www.cnblogs.com/nbwzyzngyl/p/8059692.html
Copyright © 2011-2022 走看看