zoukankan      html  css  js  c++  java
  • POJ1177 IOI 1998, Picture

    扫描线求周长

    蠢办法, 横竖都求一次
    一条周长为两条相邻扫描线长度差的绝对值

    Code

    #include<iostream>
    #include<cstdio>
    #include<queue>
    #include<cstring>
    #include<algorithm>
    #include<climits>
    #define LL long long
    #define REP(i, x, y) for(LL i = (x);i <= (y);i++)
    using namespace std;
    LL RD(){
        LL out = 0,flag = 1;char c = getchar();
        while(c < '0' || c >'9'){if(c == '-')flag = -1;c = getchar();}
        while(c >= '0' && c <= '9'){out = out * 10 + c - '0';c = getchar();}
        return flag * out;
        }
    const LL maxn = 100010;
    LL num, X[maxn << 1];
    LL tot;//去重后的横坐标数
    struct ScanLine{
    	LL h, l, r, mark;
    	bool operator < (const ScanLine &x) const {
    		return h < x.h;
    		}
    	}line[maxn << 1];
    #define lid (id << 1)
    #define rid (id << 1) | 1
    struct Seg_Tree{
    	LL l, r, tag, len;
    	}tree[maxn << 4];
    void pushup(LL id){
    	LL l = tree[id].l, r = tree[id].r;
    	if(tree[id].tag)
    		tree[id].len = X[r + 1] - X[l];
    	else
    		tree[id].len = tree[lid].len + tree[rid].len;
    	}
    void build(LL id, LL l, LL r){
    	tree[id].l = l, tree[id].r = r;
    	if(l == r){
    		tree[id].tag = tree[id].len = 0;
    		return ;
    		}
    	LL mid = (l + r) >> 1;
    	build(lid, l, mid), build(rid, mid + 1, r);
    	pushup(id);
    	}
    void update(LL id, LL L, LL R, LL val){
    	LL l = tree[id].l, r = tree[id].r;
    	if(X[l] >= R || X[r + 1] <= L)return ;
    	if(X[l] >= L && X[r + 1] <= R){
    		tree[id].tag += val;
    		pushup(id);
    		return ;
    		}
    	update(lid, L, R, val);
    	update(rid, L, R, val);
    	pushup(id);
    	}
    int data[maxn << 2], cnt;
    void read(){
    	num = RD();
    	REP(i, 1, num * 4)data[++cnt] = RD();
    	}
    //LL abs(LL x){}
    void init1(){
    	//num = RD();
    	int j = 0;
    	REP(i, 1, num){
    		LL x1 = data[++j], y1 = data[++j], x2 = data[++j], y2 = data[++j];
    		X[i * 2 - 1] = x1, X[i << 1] = x2;
    		line[i * 2 - 1] = (ScanLine){y1, x1, x2, 1};
    		line[i << 1] = (ScanLine){y2, x1, x2, -1};
    		}
    	num = num << 1;
    	sort(X + 1, X + 1 + num);
    	sort(line + 1, line + 1 + num);
    	tot = unique(X + 1, X + 1 + num) - X - 1;
    	build(1, 1, tot - 1);
    	}
    void init2(){
    	//num = RD();
    	int j = 0;
    	REP(i, 1, num){
    		LL y1 = data[++j], x1 = data[++j], y2 = data[++j], x2 = data[++j];
    		X[i * 2 - 1] = x1, X[i << 1] = x2;
    		line[i * 2 - 1] = (ScanLine){y1, x1, x2, 1};
    		line[i << 1] = (ScanLine){y2, x1, x2, -1};
    		}
    	num = num << 1;
    	sort(X + 1, X + 1 + num);
    	sort(line + 1, line + 1 + num);
    	tot = unique(X + 1, X + 1 + num) - X - 1;
    	build(1, 1, tot - 1);
    	}
    LL ans;
    void work(){
    	LL temp = 0;
    	REP(i, 1, num){
    		update(1, line[i].l, line[i].r, line[i].mark);
    		LL cao = temp - tree[1].len;
    		if(cao < 0)cao = -cao;
    		ans += cao;
    		temp = tree[1].len;
    		}
    	//
    	}
    int main(){
    	read();
    	init1();
    	work();
    	init2();
    	work();
    	cout<<ans<<endl;
    	return 0;
    	}
    
  • 相关阅读:
    51nod 1067 Bash游戏 V2
    洛谷 P1454 圣诞夜的极光 == codevs 1293 送给圣诞夜的极光
    bzoj4754: [Jsoi2016]独特的树叶
    bzoj 4241: 历史研究
    bzoj 1266 [AHOI2006] 上学路线
    bzoj4571: [Scoi2016]美味
    bzoj4570: [Scoi2016]妖怪
    51nod 1238 最小公倍数之和 V3
    一个康托展开的板子
    poweroj1745: 餐巾计划问题
  • 原文地址:https://www.cnblogs.com/Tony-Double-Sky/p/14471363.html
Copyright © 2011-2022 走看看