• [BZOJ1790][AHOI2008]Rectangle 矩形藏宝地(四维偏序,CDQ+线段树)


    1790: [Ahoi2008]Rectangle 矩形藏宝地

    Time Limit: 10 Sec  Memory Limit: 64 MB
    Submit: 553  Solved: 193
    [Submit][Status][Discuss]

    Description

    欢 乐岛上最著名的游戏是一个寻宝游戏,小可可来到宝藏的埋藏地,这是一块开阔地,宝藏被分散的埋藏在这块地下,现在要做的是一件件的把宝藏挖出来。为了提示 宝藏的埋藏点,游戏的主办方把这块开阔地当作第一象限,将所有可能埋藏宝藏的地方划成一个个矩形的土地,并把这些矩形土地的坐标都告诉了参赛者。挖宝的提 示很简单,只要某一个矩阵土地至少被另外一个矩阵土地所包含,那么这个矩阵土地里肯定埋有宝藏。其实这些宝藏都是一些精美的纪念品,如果谁挖出来了纪念品 就归谁了,小可可很想为这次旅程画上完美的句号,有你的帮助他信心十足,你只要告诉他.有多少个矩形土地里肯定埋有宝藏就行了。胜利就在眼前,加油吧!!

    Input

    第一行包含一个整数N(N≤200000),表示矩形的个数。接下来N行,每行用4个整数x1,y1,x2,y2,描述了一个矩形。其中(x1,y1)表示这个矩形左下角的坐标,(x2,y2)表示右上角的坐标,一个xi值或yi值最多出现一次.

    Output

    只包含一个整数,表示肯定埋有宝藏的矩形土地的个数。

    Sample Input

    3
    0 0 5 5
    1 2 3 4
    2 1 4 3

    Sample Output

    2

    HINT

    100%的数据中,N<=200000
    70%的数据申,N<=50000
    30%的数据中,N<=5000
    所有数据中,一个x值或Y值最多出现一次

    Source

    [Submit][Status][Discuss]

    题意显然的四维偏序,但是有不同的地方,这里求的不是满足条件的对数,而是只有0和1的判断,所以可以用三维偏序做。

    按照常规方法,对a分治,对b排序,这时候我们询问的其实就是“到当前为止的所有c'>=c的矩形中,最大的d'是否大于d”,这个就是线段树后缀最大值。

     1 #include<cstdio>
     2 #include<algorithm>
     3 #define ls (x<<1)
     4 #define rs (ls|1)
     5 #define lson ls,L,mid
     6 #define rson rs,mid+1,R
     7 #define rep(i,l,r) for (int i=l; i<=r; i++)
     8 using namespace std;
     9 
    10 const int N=200100;
    11 int n,ans,tot,b[N],res[N],tag[N],v[N<<2],mx[N<<2];
    12 struct P{ int a,b,c,d,id; }a[N],p[N];
    13 bool operator <(const P &a,const P &b){ return a.a<b.a; }
    14 bool cmp(const P &a,const P &b){ return a.b<b.b; }
    15 
    16 void upd(int x,int L,int R,int pos,int k){
    17     if (L==R){ v[x]=mx[x]=k; return; }
    18     int mid=(L+R)>>1;
    19     if (pos<=mid) upd(lson,pos,k); else upd(rson,pos,k);
    20     mx[x]=max(mx[ls],mx[rs]);
    21 }
    22 
    23 int que(int x,int L,int R,int pos){
    24     if (L==R) return mx[x];
    25     int mid=(L+R)>>1;
    26     if (pos<=mid) return max(que(lson,pos),mx[rs]);
    27         else return que(rson,pos);
    28 }
    29 
    30 void CDQ(int l,int r){
    31     if (l==r) return;
    32     int mid=(l+r)>>1;
    33     CDQ(l,mid); CDQ(mid+1,r);
    34     rep(i,l,mid) tag[a[i].id]=1;
    35     rep(i,l,r) p[i]=a[i];
    36     sort(p+l,p+r+1,cmp);
    37     rep(i,l,r){
    38         if (tag[p[i].id]) upd(1,1,n,p[i].c,p[i].d);
    39         else if (que(1,1,n,p[i].c)>p[i].d) res[p[i].id]=1;
    40     }
    41     rep(i,l,mid) upd(1,1,n,a[i].c,0),tag[a[i].id]=0;
    42 }
    43 
    44 int main(){
    45     freopen("bzoj1790.in","r",stdin);
    46     freopen("bzoj1790.out","w",stdout);
    47     scanf("%d",&n);
    48     rep(i,1,n) scanf("%d%d%d%d",&a[i].a,&a[i].b,&a[i].c,&a[i].d),b[i]=a[i].c,a[i].id=i;
    49     sort(b+1,b+n+1); tot=unique(b+1,b+n+1)-b-1;
    50     rep(i,1,n) a[i].c=lower_bound(b+1,b+tot+1,a[i].c)-b;
    51     sort(a+1,a+n+1); CDQ(1,n);
    52     rep(i,1,n) ans+=res[i]; printf("%d
    ",ans);
    53     return 0;
    54 }
  • 相关阅读:
    移植Linux2.6.38到Tiny6410_1GNandflash
    【转载】Mini6410启动过程
    【转载】Mini2440启动配置文件说明
    【转载】linux2.6内核initrd机制解析
    第十三章 StringTable
    第十二章 执行引擎
    第十一章 直接内存(Direct Memory)
    第十章 对象的实例化、内存布局与访问定位
    第九章 方法区
    第八章 堆
  • 原文地址:https://www.cnblogs.com/HocRiser/p/9049460.html
Copyright © 2020-2023  润新知