HUD 1828 Picture 矩形周長/線段樹

來源:互聯網
上載者:User

題意:求重疊矩形的周長。
題解:枚舉x區間時要注意求出, y 軸投影的線段數量。 即對應一個 x 有多少段不連續的線段,因為這關係的矩形的寬。 對 x 進行排列要記得入邊在前,出邊在後,否則邊相交的兩個矩形,就會把重邊也計算在內。

#include <cmath>#include <algorithm>#include <iostream>using namespace std;#define L(x) ( x << 1 )  #define R(x) ( x << 1 | 1 )  #define N 20010int y[N*2];struct Node {    int l, r, len, lc, rc, cover, cnt; /* lc, rc, 表示定的被覆蓋的次數 */} node[N*4];struct Line{    int x, y1, y2, flag;} line[N*2];bool cmp ( Line a, Line b ){    if ( a.x != b.x )        return a.x < b.x;    return a.flag > b.flag; /* 當 x 相同時應當是入邊在前, 畫兩個矩形分析分析 */}void y_update ( int u ){    if ( node[u].cover > 0 )        node[u].len = y[node[u].r] - y[node[u].l];    else if ( node[u].l + 1 == node[u].r )        node[u].len = 0;    else        node[u].len = node[L(u)].len + node[R(u)].len;    if ( node[u].cover > 0 )        node[u].cnt = 1; /* cnt 記錄投影到 y 軸上的線段數( 即不連續的段數) */    else    {        node[u].cnt = node[L(u)].cnt + node[R(u)].cnt;        if ( node[R(u)].lc != 0 && node[L(u)].rc != 0 )  /*左子樹的右端點如果跟右子樹的左端點都被覆蓋了,說明在整個區間裡,有一個區間橫跨左右子樹,但被重複計算了,所以要減去1 */            node[u].cnt--;    }}void build( int u, int l, int r ){    node[u].l = l;       node[u].r = r;    node[u].cnt = 0;    node[u].len = node[u].cover = 0;    node[u].lc = node[u].rc = 0;    if ( l + 1 == r ) return;    int mid = ( l + r ) >> 1;    build ( L(u), l, mid );    build ( R(u), mid, r );}void update ( int u, Line e ){      if ( e.y1 == y[node[u].l] )        node[u].lc += e.flag;    if ( e.y2 == y[node[u].r] )        node[u].rc += e.flag;    if ( e.y1 == y[node[u].l] && e.y2 == y[node[u].r] )    {        node[u].cover += e.flag;         y_update ( u );        return;    }    if ( e.y1 >= y[node[R(u)].l] )        update ( R(u), e );    else if ( e.y2 <= y[node[L(u)].r] )        update ( L(u), e );    else    {        Line temp1 = e;        Line temp2 = e;        temp1.y2 = y[node[L(u)].r];        temp2.y1 = y[node[R(u)].l];        update ( L(u), temp1 );        update ( R(u), temp2 );    }    y_update ( u );}int main(){    //freopen ( "a.txt", "r", stdin );    int n, i, k, x1, y1, x2, y2;    while ( scanf("%d",&n) != EOF )    {        for ( i = k = 1; i <= n; i++, k++ )        {            scanf("%d %d %d %d", &x1, &y1, &x2, &y2 );            line[k].x = x1;            line[k].y1 = y1;            line[k].y2 = y2;            line[k].flag = 1;            y[k] = y1;            k++;            line[k].x = x2;            line[k].y1 = y1;            line[k].y2 = y2;            line[k].flag = -1;            y[k] = y2;        }        sort ( line+1, line+k, cmp );        sort ( y+1, y+k );        build ( 1, 1, k-1 );        update ( 1, line[1] );        int ans = node[1].len;        int temp = node[1].len;        int tcnt = node[1].cnt;        for ( i = 2; i < k; i++ )        {            update ( 1, line[i] );            ans += abs ( node[1].len - temp );            ans += 2 * ( line[i].x - line[i-1].x ) * tcnt;            temp = node[1].len;            tcnt = node[1].cnt;        }        printf ( "%d\n", ans );    }    return 0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.