【HDU】1828-Picture(线段树扫描线)

来源:互联网 发布:中国网络资讯台 山寨 编辑:程序博客网 时间:2024/06/05 07:29

矩阵交并周长的模板题

这题不需要离散化,需要注意的时候负坐标转化成正坐标

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define lson (pos<<1)#define rson (pos<<1|1)typedef long long LL;const int maxn = 30005;const int ADD  = 10001;struct Seg{    int l,r,c,h;    Seg(int l = 0,int r = 0,int h = 0,int c = 0):l(l),r(r),h(h),c(c){};    friend bool operator < (Seg p,Seg q){        return p.h < q.h;    }}seg[maxn];struct Node{    int l,r,cover,sum1,sum2;    bool left,right;    int mid(){        return (l + r) >> 1;    }    int len(){        return  r - l + 1;    }}node[maxn << 2];int cnt;void build(int l,int r,int pos){    node[pos].l = l; node[pos].r = r;    node[pos].sum1 = node[pos].sum2 = 0;    node[pos].left = node[pos].right = false;    node[pos].cover = 0;    if(l == r) return;    int mid = (l + r) >> 1;    build(l,mid,lson);    build(mid + 1,r,rson);}void pushup(int pos){    if(node[pos].cover){        node[pos].sum1 = 2;        node[pos].sum2 = node[pos].len();        node[pos].left = node[pos].right = true;    }    else if(node[pos].len() == 1){        node[pos].sum1 = node[pos].sum2 = node[pos].left = node[pos].right = 0;    }    else{        node[pos].sum1  = node[lson].sum1 + node[rson].sum1;        if(node[lson].right && node[rson].left) node[pos].sum1 -= 2;        node[pos].sum2  = node[lson].sum2 + node[rson].sum2;        node[pos].left  = node[lson].left;        node[pos].right = node[rson].right;    }}void update(int l,int r,int pos,int d){    if(l <= node[pos].l && node[pos].r <= r){        node[pos].cover += d;        pushup(pos);        return;    }    int mid = node[pos].mid();    if(l <= mid)        update(l,r,lson,d);    if(r  > mid)        update(l,r,rson,d);    pushup(pos);    return;}int main(){    int n;    while(scanf("%d",&n) != EOF){        build(1,30000,1);        cnt = 0;        for(int i = 0; i < n; i++){            int a,b,c,d;            scanf("%d%d%d%d",&a,&b,&c,&d);            a += ADD; c += ADD;            seg[cnt++] = Seg(a,c,d,1);            seg[cnt++] = Seg(a,c,b,-1);        }        sort(seg,seg + cnt);        LL ans = 0,last = 0;        for(int i = 0; i < cnt; i++){            int l = seg[i].l,r = seg[i].r,c = seg[i].c;            update(l,r - 1,1,c);            if(i < cnt - 1)                ans += node[1].sum1 * (seg[i + 1].h - seg[i].h);            ans += abs(node[1].sum2 - last);            last = node[1].sum2;        }        printf("%I64d\n",ans);    }    return 0;}

0 0
原创粉丝点击