码迷,mamicode.com
首页 > 其他好文 > 详细

poj 1177 Picture 线段树辅助解扫描线 矩形周长并

时间:2015-01-17 19:29:31      阅读:215      评论:0      收藏:0      [点我收藏+]

标签:

题目链接:http://poj.org/problem?id=1177

分析:对扫描线不太理解~~~ 第一题~~

   留个坑。

 

代码:

  

/* ***********************************************
Author        :ltwy
Created Time  :2015年01月17日 星期六 18时06分53秒
File Name     :1.cpp
************************************************ */

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
const int MAXN = 10010;
int n;
int x[MAXN];
int num = 0;
struct Line
{
    int y, x1, x2;
    int f;
}line[MAXN];
struct node
{
    int l,r;
    int cnt;
    int lf, rf;
    int numseg;
    int c;
    bool lcover,rcover;
}tree[MAXN<<2];
bool cmp(Line a, Line b)
{
    return a.y < b.y;
}
void build(int rt, int l, int r)
{
    tree[rt].l = l;
    tree[rt].r = r;
    tree[rt].cnt = tree[rt].numseg = tree[rt].c = 0;
    tree[rt].lcover = tree[rt].rcover = false;
    tree[rt].lf = x[l];
    tree[rt].rf = x[r];
    if(l + 1 == r)
        return;
    int mid = (l+r)>>1;
    build(rt<<1, l, mid);
    build(rt<<1|1, mid, r);
}
void calen(int rt)
{
    if(tree[rt].c > 0)
    {
        tree[rt].numseg = 1;
        tree[rt].cnt = tree[rt].rf - tree[rt].lf;
        tree[rt].lcover = tree[rt].rcover = true;
        return;
    }
    if(tree[rt].l + 1 == tree[rt].r)
    {
        tree[rt].cnt = 0;
        tree[rt].numseg = 0;
        tree[rt].lcover = tree[rt].rcover = false;
    }
    else
    {
        tree[rt].cnt = tree[rt<<1].cnt + tree[rt<<1|1].cnt;
        tree[rt].lcover = tree[rt<<1].lcover;
        tree[rt].rcover = tree[rt<<1|1].rcover;
        tree[rt].numseg = tree[rt<<1].numseg + tree[rt<<1|1].numseg;
        if(tree[rt<<1].rcover&&tree[rt<<1|1].lcover) tree[rt].numseg --;
    }
}
void update(int rt, Line e)
{
    if(tree[rt].lf == e.x1 && tree[rt].rf == e.x2)
    {
        tree[rt].c += e.f;
        calen(rt);
        return;
    }
    if(e.x2 <= tree[rt<<1].rf) update(rt<<1, e);
    else if(e.x1 >= tree[rt<<1|1].lf) update(rt<<1|1, e);
    else
    {
        Line temp = e;
        temp.x2 = tree[rt<<1].rf;
        update(rt<<1, temp);
        temp = e;
        temp.x1 = tree[rt<<1|1].lf;
        update(rt<<1|1, temp);
    }
    calen(rt);
}
int main()
{
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    int x1,y1,x2,y2;
    while(scanf("%d", &n) != EOF)
    {
        num = 0;
        for(int i=1; i<=n; i++)
        {
            scanf("%d %d %d %d", &x1, &y1, &x2, &y2);
            line[num].y = y1;
            line[num].x1 = x1;
            x[num] = x1;
            line[num].f = 1;
            line[num++].x2 = x2;
            line[num].y = y2;
            line[num].x1 = x1;
            x[num] = x2;
            line[num].f = -1;
            line[num++].x2 = x2;
        }
        sort(line, line+num, cmp);
        sort(x, x+num);
        int m = unique(x, x+num) - x;
        build(1, 1, m);
        int ans = 0;
        int last = 0;
        for(int i=0; i<num-1; i++)
        {
            update(1, line[i]);
            ans += tree[1].numseg * 2 * (line[i+1].y - line[i].y);
            ans += abs(tree[1].cnt - last);
            last = tree[1].cnt;
        }
        update(1, line[num-1]);
        ans += abs(tree[1].cnt - last);
        printf("%d\n", ans);
    }
    return 0;
}

 

poj 1177 Picture 线段树辅助解扫描线 矩形周长并

标签:

原文地址:http://www.cnblogs.com/ltwy/p/4230927.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!