zoukankan      html  css  js  c++  java
  • BZOJ 4237: 稻草人

    4237: 稻草人

    Time Limit: 40 Sec  Memory Limit: 256 MB
    Submit: 661  Solved: 286
    [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

    [Submit][Status][Discuss]

    将y这一维分治一下,每次考虑一个平面,中间割开,下面每个点作为左下点时,上面可以和其配对的右上点的个数。

    将所有点按x维排序,扫描线从右向左,上面维护一个单调上升的栈,下面维护一个单调下降的栈,每次拿到下面一个点时,先在下面的栈中二分出第一个y大于它的点,这个点的x坐标是不可逾越的。然后二分出上面栈中有多少个点在这个界限以左,就是这个左下点的合法配对数。

    UPDATE 2/18 补代码

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <algorithm>
      4 
      5 using namespace std;
      6 
      7 template <class T>
      8 __inline void read(T &x)
      9 {
     10     x = 0;
     11     char c = getchar();
     12     while (c < 48)c = getchar();
     13     while (c > 47)x = x*10 + c - 48, c = getchar();
     14 }
     15 
     16 #define rep(i,x,y) for(register int i=x;i<=y;++i)
     17 #define per(i,x,y) for(register int i=x;i>=y;--i)
     18 
     19 const int mxn = 2E5 + 5;
     20 const int inf = 1E9 + 7;
     21 
     22 int n; long long sum;
     23 
     24 struct pii
     25 {
     26     int x, y;
     27 }p[mxn];
     28 
     29 inline bool cmpX(const pii &a, const pii &b)
     30 {
     31     return a.x < b.x;
     32 }
     33 
     34 inline bool cmpY(const pii &a, const pii &b)
     35 {
     36     return a.y < b.y;
     37 }
     38 
     39 void solve(int l, int r)
     40 {
     41     if (l == r)return;
     42     
     43     int m = (l + r) >> 1;
     44     
     45     nth_element(
     46         p + l,
     47         p + m,
     48         p + r + 1,
     49         cmpY);
     50         
     51     int h = p[m].y;
     52     
     53     solve(l, m);
     54     solve(m + 1, r);
     55     
     56     static pii s[mxn]; 
     57     
     58     int t = 0, a = l, b = m + 1;
     59     
     60     while (a <= m && b <= r)
     61     {
     62         if (p[a].x < p[b].x)
     63             s[t++] = p[a++];
     64         else
     65             s[t++] = p[b++];
     66     }
     67     
     68     while (a <= m)s[t++] = p[a++];
     69     while (b <= r)s[t++] = p[b++];
     70     
     71     memcpy(p + l, s, t * sizeof(pii));
     72     
     73     static pii sa[mxn]; int ta = 0;
     74     static pii sb[mxn]; int tb = 0;
     75     
     76     per (i, r, l)
     77     {
     78         if (p[i].y > h)
     79         {
     80             while (ta && p[i].y < sa[ta].y)--ta; sa[++ta] = p[i];
     81         }
     82         else
     83         {
     84             int ans = 0, lim = p[i].y;
     85             
     86             {
     87                 int lt = 1, rt = tb, mid;
     88                 
     89                 while (lt <= rt)
     90                 {
     91                     mid = (lt + rt) >> 1;
     92                     
     93                     if (sb[mid].y > lim)
     94                         lt = mid + 1, ans = mid;
     95                     else
     96                         rt = mid - 1;
     97                 }
     98             }
     99             
    100             if (ans)
    101                 lim = sb[ans].x;
    102             else
    103                 lim = inf;
    104                 
    105             ans = 0;
    106                 
    107             {
    108                 int lt = 1, rt = ta, mid;
    109                 
    110                 while (lt <= rt)
    111                 {
    112                     mid = (lt + rt) >> 1;
    113                     
    114                     if (sa[mid].x > lim)
    115                         lt = mid + 1, ans = mid;
    116                     else
    117                         rt = mid - 1;
    118                 }
    119             }
    120             
    121             sum += ta - ans;
    122             
    123             while (tb && p[i].y > sb[tb].y)--tb; sb[++tb] = p[i];
    124         }
    125     }
    126 }
    127 
    128 signed main(void)
    129 {
    130     read(n);
    131     
    132     rep (i, 1, n)
    133         read(p[i].x),
    134         read(p[i].y);
    135     
    136     sort(p + 1, p + n + 1, cmpX); rep (i, 1, n)p[i].x = i;
    137     sort(p + 1, p + n + 1, cmpY); rep (i, 1, n)p[i].y = i;
    138     
    139     solve(1, n), printf("%lld
    ", sum);
    140 }

    @Author: YouSiki

  • 相关阅读:
    Django--URLconf
    Django--视图层
    Django 初识之安装下载以及模型目录简介
    jQuery基础
    BOM&DOM
    带你快速上手前端三剑客之css
    mysql 触发器、流程控制、事务等
    前端之html
    python中pymsql常用方法(1)
    18、设计模式-行为型模式-迭代器模式
  • 原文地址:https://www.cnblogs.com/yousiki/p/6412227.html
Copyright © 2011-2022 走看看