POJ

来源:互联网 发布:dota2位置 知乎 编辑:程序博客网 时间:2024/05/16 11:38

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

题目大意:求矩形的周长并

解题思路:与求矩形面积并思路一致,但是需要对y轴和x轴进行两次扫描,而周长的变化为两次相邻sum的差

参考博客:http://blog.csdn.net/lwt36/article/details/48908031

AC代码:

#include<cstdio>#include<algorithm>using namespace std;const int MAXN = 10000 + 5;struct Segment{    int l, r, h,flag;    Segment(int l = 0, int r = 0, int h = 0, int flag = 0) :        l(l), r(r), h(h), flag(flag) {}    bool operator<(const Segment& a)const { return h < a.h; }}seg1[MAXN],seg2[MAXN];int pos1[MAXN], pos2[MAXN];int sum[MAXN << 2], tag[MAXN << 2];int binarySearch(int l, int r, int val,int *arr){    while (l <= r)    {        int mid = (l + r) >> 1;        if (arr[mid] == val) return mid;        else if (arr[mid] < val) l = mid + 1;        else r = mid - 1;    }    return -1;}void buildTree(int L,int R,int rt){    sum[rt] = tag[rt] = 0;    if (L == R)        return;    int mid = (L + R) >> 1;    buildTree(L, mid, rt << 1);    buildTree(mid + 1, R, rt << 1 | 1);}void pushUp(int l, int r, int rt,int *pos){    if (tag[rt]) sum[rt] = pos[r + 1] - pos[l];    else if (l == r) sum[rt] = 0;    else sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];}void upDate(int L, int R, int v, int l, int r, int rt, int *pos){    if (L <= l && r <= R)    {        tag[rt] += v;        pushUp(l, r, rt, pos);        return;    }    int m = (l + r) >> 1;    if (L <= m) upDate(L, R, v, l, m, rt << 1, pos);    if (R > m) upDate(L, R, v, m + 1, r, rt << 1 | 1, pos);    pushUp(l, r, rt, pos);}int main(){    for (int n;scanf("%d", &n) == 1;)    {        if (n == 0) continue;        int x1, y1, x2, y2;        for (int i = 1;i <= n;++i)        {            scanf("%d%d%d%d", &x1, &y1, &x2, &y2);            seg1[i] = Segment(x1, x2, y1, 1);            seg1[i + n] = Segment(x1, x2, y2, -1);            pos1[i] = x1, pos1[i + n] = x2;            seg2[i] = Segment(y1, y2, x1, 1);            seg2[i + n] = Segment(y1, y2, x2, -1);            pos2[i] = y1, pos2[i + n] = y2;        }        sort(seg1 + 1, seg1 + 2 * n + 1);        sort(pos1 + 1, pos1 + 2 * n + 1);        sort(seg2 + 1, seg2 + 2 * n + 1);        sort(pos2 + 1, pos2 + 2 * n + 1);        int end1 = unique(pos1 + 1, pos1 + 2 * n + 1) - pos1 - 1;        int end2 = unique(pos2 + 1, pos2 + 2 * n + 1) - pos2 - 1;        int ans = 0, presum = 0;        buildTree(1, end1, 1);        for (int i = 1;i <= 2 * n;i++)        {            int l = binarySearch(1, end1, seg1[i].l, pos1);            int r = binarySearch(1, end1, seg1[i].r, pos1);            if (l < r) upDate(l, r - 1, seg1[i].flag, 1, end1, 1, pos1);            ans += abs(sum[1] - presum);            presum = sum[1];        }        buildTree(1, end2, 1);        presum = 0;        for (int i = 1;i <= 2 * n;i++)        {            int l = binarySearch(1, end2, seg2[i].l, pos2);            int r = binarySearch(1, end2, seg2[i].r, pos2);            if (l < r) upDate(l, r - 1, seg2[i].flag, 1, end2, 1, pos2);            ans += abs(sum[1] - presum);            presum = sum[1];        }        printf("%d\n", ans);    }    return 0;}
原创粉丝点击