• 【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;
        
    }
  • 相关阅读:
    DICOM:DICOM3.0网络通信协议
    Maven使用—拷贝Maven依赖jar包到指定目录
    Spring Boot使用JavaMailSender发送邮件
    SpringBoot配置Email发送功能
    MariaDB 安装与启动 过程记录
    ESXi与Linux主机配置syslog日志上传远程服务器
    Linux--忘记MySQL密码的解决方法和输入mysqld_safe --skip-grant-tables &后无法进入MySQL的解决方法
    centos killall安装
    centos安装lspci工具
    oracle创建job和删除job
  • 原文地址:https://www.cnblogs.com/evenbao/p/9196354.html
Copyright © 2020-2023  润新知