POJ

来源:互联网 发布:机器人算法工程师 编辑:程序博客网 时间:2024/06/16 21:49

POJ - 1177 Picture

线段树扫描线求矩形周长并

#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>#include <bitset>#define INF 0x3f3f3f3f#define eps 1e-6#define PI 3.1415926#define mod 1000000009#define base 2333using namespace std;typedef long long LL;const int maxn = 1e4 + 10;const int maxx = 1e3 + 10;inline void splay(int &v) {    v=0;char c=0;int p=1;    while(c<'0' || c >'9'){if(c=='-')p=-1;c=getchar();}    while(c>='0' && c<='9'){v=(v<<3)+(v<<1)+c-'0';c=getchar();}    v*=p;}int n, Hash[maxn];struct edge {    int x1, x2, h, cur;    edge(int x1 = 0, int x2 = 0, int h = 0, int cur = 0):        x1(x1), x2(x2), h(h), cur(cur) {}    bool operator <(const edge &a) const {        return h < a.h;    }} seg[maxn];struct Tree {    int l, r, m, len, mark, num;    bool lc, rc;} tr[maxn<<2];void PushUp(int id) {    if(tr[id].mark) {        tr[id].len = Hash[tr[id].r+1]-Hash[tr[id].l];        tr[id].lc = tr[id].rc = 1;        tr[id].num = 1;    }    else if(tr[id].l == tr[id].r) {        tr[id].len = tr[id].num = 0;        tr[id].lc = tr[id].rc = 0;    }    else {        tr[id].len = tr[id<<1].len+tr[id<<1|1].len;        tr[id].lc = tr[id<<1].lc, tr[id].rc = tr[id<<1|1].rc;        tr[id].num = tr[id<<1].num+tr[id<<1|1].num-(tr[id<<1].rc&tr[id<<1|1].lc);        //去重    }}void build(int id, int l, int r) {    tr[id].l = l, tr[id].r = r, tr[id].m = (l+r)>>1;    tr[id].mark = tr[id].len = tr[id].num = 0;    tr[id].lc = tr[id].rc = 0;    if(l == r) return ;    build(id<<1, l, tr[id].m);    build(id<<1|1, tr[id].m+1, r);}void update(int id, int l, int r, int d) {    if(l <= tr[id].l && r >= tr[id].r)        tr[id].mark += d;    else {        if(l <= tr[id].m) update(id<<1, l, r, d);        if(r > tr[id].m) update(id<<1|1, l, r, d);    }    PushUp(id);}void solve() {    while(scanf("%d", &n) != EOF) {        int x1, x2, y1, y2;        int k = 0, m = 1, ans = 0, last = 0;        for(int i = 0; i < n; i++) {            splay(x1), splay(y1), splay(x2), splay(y2);            seg[++k] = edge(x1, x2, y1, 1);            Hash[k] = x1;            seg[++k] = edge(x1, x2, y2, -1);            Hash[k] = x2;        }        sort(Hash+1, Hash+k+1);        sort(seg+1, seg+k+1);        for(int i = 1; i < k; i++) {           //离散化            if(Hash[i] != Hash[i+1])                Hash[++m] = Hash[i+1];        }        build(1, 1, m);        for(int i = 1; i <= k; i++) {            int L = lower_bound(Hash+1, Hash+m+1, seg[i].x1)-Hash;            int R = lower_bound(Hash+1, Hash+m+1, seg[i].x2)-Hash-1;            update(1, L, R, seg[i].cur);            ans += abs(tr[1].len-last);                //求横边            ans += (seg[i+1].h-seg[i].h)*2*tr[1].num;  //求纵边            last = tr[1].len;        }        printf("%d\n", ans);    }}int main() {    //srand(time(NULL));    //freopen("kingdom.in","r",stdin);    //freopen("kingdom.out","w",stdout);    solve();}


原创粉丝点击