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;
	}
原文地址:https://www.cnblogs.com/Tony-Double-Sky/p/14471363.html