zoukankan      html  css  js  c++  java
  • [HDOJ1828]Picture(扫描线,线段树,矩形并周长)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1828

    题意:求矩形并的周长。

    很好发现一个规律,那就是扫描到当前状态,update之后的线段树中线段的长度减去update之前的长度差的绝对值恰好是当前段并后的水平或者垂直的线段长度。

    那么。。存两棵线段树,横着扫一遍竖着扫一遍,加起来就行了。。

    竟然没MLE。。。

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 
      4 #define lrt rt << 1
      5 #define rrt rt << 1 | 1
      6 const int maxn = 5500;
      7 typedef struct Event {
      8     double l, r, hx;
      9     int sign;
     10 }Event;
     11 typedef struct Seg {
     12     double len;
     13     int sign;
     14 }Seg;
     15 
     16 vector<Event> event1, event2;
     17 double hx[maxn<<1], hy[maxn<<1];
     18 Seg seg[maxn<<2];
     19 int hxcnt, hycnt;
     20 int n;
     21 
     22 bool cmp(Event a, Event b) {
     23     if(a.hx != b.hx) return a.hx < b.hx;
     24     return a.sign > b.sign;
     25 }
     26 
     27 int xid(double x) {
     28     return lower_bound(hx, hx+hxcnt, x) - hx + 1;
     29 }
     30 
     31 int yid(double y) {
     32     return lower_bound(hy, hy+hycnt, y) - hy + 1;
     33 }
     34 
     35 void build(int l, int r, int rt) {
     36     seg[rt].len = .0; seg[rt].sign = 0;
     37     if(l == r) return;
     38     int mid = (l + r) >> 1;
     39     build(l, mid, lrt);
     40     build(mid+1, r, rrt);
     41 }
     42 
     43 void pushup(int l, int r, int rt) {
     44     if(seg[rt].sign) seg[rt].len = hx[r] - hx[l-1];
     45     else {
     46         if(l == r) seg[rt].len = .0;
     47         else seg[rt].len = seg[lrt].len + seg[rrt].len;
     48     }
     49 }
     50 
     51 void pushup1(int l, int r, int rt) {
     52     if(seg[rt].sign) seg[rt].len = hy[r] - hy[l-1];
     53     else {
     54         if(l == r) seg[rt].len = .0;
     55         else seg[rt].len = seg[lrt].len + seg[rrt].len;
     56     }
     57 }
     58 
     59 void update(bool flag, int L, int R, int sign, int l, int r, int rt) {
     60     if(L <= l && r <= R) {
     61         seg[rt].sign += sign;
     62         if(!flag) pushup(l, r, rt);
     63         else pushup1(l, r, rt);
     64         return;
     65     }
     66     int mid = (l + r) >> 1;
     67     if(L <= mid) update(flag, L, R, sign, l, mid, lrt);
     68     if(mid < R) update(flag, L, R, sign, mid+1, r, rrt);
     69     if(!flag) pushup(l, r, rt);
     70     else pushup1(l, r, rt);
     71 }
     72 
     73 int main() {
     74     // freopen("in", "r", stdin);
     75     int _ = 1;
     76     double ax, ay, bx, by;
     77     while(~scanf("%d",&n)) {
     78         hxcnt = 0; event1.clear(); event2.clear();
     79         for(int i = 0; i < n; i++) {
     80             scanf("%lf%lf%lf%lf",&ax,&ay,&bx,&by);
     81             event1.push_back({ax, bx, ay, 1});
     82             event1.push_back({ax, bx, by, -1});
     83             event2.push_back({ay, by, ax, 1});
     84             event2.push_back({ay, by, bx, -1});
     85             hx[hxcnt++] = ax; hx[hxcnt++] = bx;
     86             hy[hycnt++] = ay; hy[hycnt++] = by;
     87         }
     88         sort(event1.begin(), event1.end(), cmp);
     89         sort(event2.begin(), event2.end(), cmp);
     90         sort(hx, hx+hxcnt); hxcnt = unique(hx, hx+hxcnt) - hx;
     91         sort(hy, hy+hycnt); hycnt = unique(hy, hy+hycnt) - hy;
     92         build(1, hxcnt, 1);
     93         double ret = .0;
     94         double pre = .0;
     95         for(int i = 0; i < event1.size(); i++) {
     96             int l = xid(event1[i].l);
     97             int r = xid(event1[i].r) - 1;
     98             int sign = event1[i].sign;
     99             update(0, l, r, sign, 1, hxcnt, 1);
    100             ret += abs(seg[1].len - pre);
    101             pre = seg[1].len;
    102         }
    103         event1.clear();
    104         build(1, hycnt, 1);
    105         pre = .0;
    106         for(int i = 0; i < event2.size(); i++) {
    107             int l = yid(event2[i].l);
    108             int r = yid(event2[i].r) - 1;
    109             int sign = event2[i].sign;
    110             update(1, l, r, sign, 1, hycnt, 1);
    111             ret += abs(seg[1].len - pre);
    112             pre = seg[1].len;
    113         }
    114         cout << ret << endl;
    115     }
    116     return 0;
    117 }
  • 相关阅读:
    数据结构化与保存
    使用正则表达式,取得点击次数,函数抽离
    爬取校园新闻首页的新闻
    网络爬虫基础练习
    综合练习:词频统计
    Hadoop综合大作业
    理解MapReduce
    熟悉常用的Hbase操作
    熟悉的HDFS操作
    爬取晨星网对各公司主要职位的分析
  • 原文地址:https://www.cnblogs.com/kirai/p/6809700.html
Copyright © 2011-2022 走看看