【IOI 1998】 Picture

【题目链接】

              点击打开链接

【算法】

          线段树扫描线求周长并

【代码】

          

#include <algorithm>
#include <bitset>
#include <cctype>
#include <cerrno>
#include <clocale>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <exception>
#include <fstream>
#include <functional>
#include <limits>
#include <list>
#include <map>
#include <iomanip>
#include <ios>
#include <iosfwd>
#include <iostream>
#include <istream>
#include <ostream>
#include <queue>
#include <set>
#include <sstream>
#include <stdexcept>
#include <streambuf>
#include <string>
#include <utility>
#include <vector>
#include <cwchar>
#include <cwctype>
#include <stack>
#include <limits.h>
using namespace std;
#define MAXN 5010
 
 int i,L,R,l1,l2,ans,last,n,xa,xb,ya,yb;
 int x[MAXN*2];
 
struct info {
        int l,r,h,opt;        
} y[MAXN*2];
struct Node {
        int l,r,sum,cnt,c;
        bool lc,rc;    
} Tree[MAXN*10];

bool cmp(info a,info b) { return a.h > b.h; }
template <typename T> inline void read(T &x) {
        int f = 1; x = 0;
        char c = getchar();
        for (; !isdigit(c); c = getchar()) { if (c == '-') f = -f; }
        for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
        x *= f;
}
template <typename T> inline void write(T x) {
    if (x < 0) { putchar('-'); x = -x; }
    if (x > 9) write(x/10);
    putchar(x%10+'0');
}
template <typename T> inline void writeln(T x)  {
    write(x);
    puts("");
}
inline void build(int index,int l,int r) {
        int mid;
        Tree[index].l = l;
        Tree[index].r = r;
        Tree[index].c = Tree[index].sum = Tree[index].cnt = 0;
        Tree[index].lc = Tree[index].rc = false;
        if (l == r) return;
        mid = (l + r) >> 1;
        build(index<<1,l,mid);
        build(index<<1|1,mid+1,r);
}
inline void push_up(int index) {
        if (Tree[index].c > 0) {
                Tree[index].sum = x[Tree[index].r+1] - x[Tree[index].l];
                Tree[index].cnt = 1;
                Tree[index].lc = Tree[index].rc = true;
        } else if (Tree[index].l == Tree[index].r) {
                    Tree[index].sum = Tree[index].cnt = 0;
                    Tree[index].lc = Tree[index].rc = false;
        } else {
                    Tree[index].lc = Tree[index<<1].lc;
                    Tree[index].rc = Tree[index<<1|1].rc;
                    Tree[index].sum = Tree[index<<1].sum + Tree[index<<1|1].sum;
                    Tree[index].cnt = Tree[index<<1].cnt + Tree[index<<1|1].cnt;
                    if (Tree[index<<1].rc && Tree[index<<1|1].lc) Tree[index].cnt--;
        }
}
inline void update(int index,int l,int r,int val) {
        int mid;
        if (Tree[index].l == l && Tree[index].r == r) {
                Tree[index].c += val;
                push_up(index);
                return;
        }    
        mid = (Tree[index].l + Tree[index].r) >> 1;
        if (mid >= r) update(index<<1,l,r,val);
        else if (mid + 1 <= l) update(index<<1|1,l,r,val);
        else {
                update(index<<1,l,mid,val);
                update(index<<1|1,mid+1,r,val);
        }
        push_up(index);
}

int main() {
        
        scanf("%d",&n); 
                l1 = l2 = 0;
                for (i = 1; i <= n; i++) {
                        read(xa); read(ya); read(xb); read(yb);
                        x[++l1] = xa;
                        x[++l1] = xb;
                        y[++l2] = (info){xa,xb,ya,-1};
                        y[++l2] = (info){xa,xb,yb,1};                
                } 
                l1 = unique(x+1,x+l1+1) - x;
                sort(x+1,x+l1+1);
                build(1,1,l1-1);
                sort(y+1,y+l2+1,cmp);
                ans = last = 0;
                for (i = 1; i < l2; i++) {
                        L = lower_bound(x+1,x+l1+1,y[i].l) - x;
                        R = lower_bound(x+1,x+l1+1,y[i].r) - x - 1;
                        update(1,L,R,y[i].opt);
                        ans += Tree[1].cnt * 2 * (y[i].h - y[i+1].h);
                        ans += abs(Tree[1].sum - last);
                        last = Tree[1].sum;
                }
                L = lower_bound(x+1,x+l1+1,y[l2].l) - x;
                R = lower_bound(x+1,x+l1+1,y[l2].r) - x - 1;
                update(1,L,R,y[l2].opt);
                ans += abs(Tree[1].sum - last);
                writeln(ans);
        
        
        return 0;
    
}

 

posted @ 2018-05-01 22:31  evenbao  阅读(302)  评论(0编辑  收藏  举报