• [BZOJ4237]稻草人 cdq分治+单调栈


    4237: 稻草人

    Time Limit: 40 Sec  Memory Limit: 256 MB
    Submit: 1340  Solved: 589
    [Submit][Status][Discuss]

    Description

    JOI村有一片荒地,上面竖着N个稻草人,村民们每年多次在稻草人们的周围举行祭典。
    有一次,JOI村的村长听到了稻草人们的启示,计划在荒地中开垦一片田地。和启示中的一样,田地需要满足以下条件:
    田地的形状是边平行于坐标轴的长方形;
    左下角和右上角各有一个稻草人;
    田地的内部(不包括边界)没有稻草人。
    给出每个稻草人的坐标,请你求出有多少遵从启示的田地的个数

    Input

    第一行一个正整数N,代表稻草人的个数
    接下来N行,第i行(1<=i<=N)包含2个由空格分隔的整数Xi和Yi,表示第i个稻草人的坐标

    Output

    输出一行一个正整数,代表遵从启示的田地的个数

    Sample Input

    4
    0 0
    2 2
    3 4
    4 3

    Sample Output

    3

    HINT

    所有满足要求的田地由下图所示:

     

    1<=N<=2*10^5

    0<=Xi<=10^9(1<=i<=N)

    0<=Yi<=10^9(1<=i<=N)

    Xi(1<=i<=N)互不相同。

    Yi(1<=i<=N)互不相同。

     

    Source

    JOI 2013~2014 春季training合宿 竞技3 By PoPoQQQ

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<cstdlib>
     5 #include<cmath>
     6 #include<algorithm>
     7 #define ll long long
     8 using namespace std;
     9 struct data {
    10     int x,y;
    11 }a[200005],sta2[200005],sta1[200005];
    12 int n;
    13 bool cmp1(data t1,data t2) {return t1.x==t2.x?t1.y<t2.y:t1.x<t2.x;}
    14 bool cmp2(data t1,data t2) {return t1.y==t2.y?t1.x<t2.x:t1.y<t2.y;}
    15 ll ans=0,tot1,tot2;
    16 void cdq(int l,int r) {
    17     int mid=l+r>>1;
    18     if(l==r) return;
    19     cdq(l,mid);cdq(mid+1,r);
    20     sort(a+l,a+mid+1,cmp2);
    21     sort(a+mid+1,a+r+1,cmp2);
    22     int tot1=tot2=0,now=l;
    23     for(int i=mid+1;i<=r;i++) {
    24         while(tot1&&sta1[tot1].x>=a[i].x) tot1--;
    25         sta1[++tot1]=a[i];
    26         while(now<=mid&&a[now].y<a[i].y) {
    27             while(tot2&&sta2[tot2].x<=a[now].x) tot2--;
    28             sta2[++tot2]=a[now++];
    29         }
    30         ans+=(long long)(tot2-(lower_bound(sta2+1,sta2+tot2+1,sta1[tot1-1],cmp2)-sta2)+1);
    31     }
    32 }
    33 int main() {
    34     sta1[0]=sta2[0]=(data){-1,-1};
    35     scanf("%d",&n);
    36     for(int i=1;i<=n;i++) scanf("%d%d",&a[i].x,&a[i].y);
    37     sort(a+1,a+n+1,cmp1);
    38     cdq(1,n);
    39     printf("%lld
    ",ans);
    40 }
    View Code
    O(∩_∩)O~ (*^__^*) 嘻嘻…… O(∩_∩)O哈哈~
  • 相关阅读:
    flush()方法
    多对一关联映射(manytoone)
    Hibernate配置数据库解决插入乱码问题
    lazy
    一对多关联映射(单向)
    属性类的映射
    多对多关联(双向)
    多对多关联映射(单向)
    多态查询
    Visual C# 2008+SQL Server 2005 数据库与网络开发11.2.2 LINQ的基本查询操作
  • 原文地址:https://www.cnblogs.com/wls001/p/8435113.html
Copyright © 2020-2023  润新知