记录编号 83388 评测结果 AAAAA
题目名称 [IOI 1998] 矩形周长 最终得分 100
用户昵称 Gravatarcstdio 是否通过 通过
代码语言 C++ 运行时间 0.050 s
提交时间 2013-12-02 21:08:01 内存使用 2.19 MiB
显示代码纯文本
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<map>
#include<cstring>
#include<vector>
#include<cmath>
#include<algorithm>
#include<iomanip>
#include<queue>
using namespace std;
const int SIZEL=41001;
const int SIZEN=5001;
const int MINC=-10000,MAXC=10000;
class SEGMENT{
public:
	int left,right;
	int lchild,rchild;
	int len;//被覆盖长度
	int count;//被覆盖次数
};
class ORDER{//操作命令
public:
	bool type;//0是去掉1是加上
	int pos;//位置(如果是横线就意味着y坐标)
	int l,r;//区间
};
bool operator < (ORDER a,ORDER b){
	return a.pos<b.pos;
	return a.type>b.type;
}
#define now tree[root]
#define lson tree[now.lchild]
#define rson tree[now.rchild]
class SEGMENT_TREE{
public:
	SEGMENT tree[SIZEL];
	int tot;
	vector<ORDER> opt;//操作序列
	int cflen;//周界长度
	SEGMENT_TREE(){
		tot=0;
		cflen=0;
	}
	void build(int,int,int);
	void build(int,int);
	void update(int);
	void section_add(int,int,int,int);
	void section_add(int,int,int);
	int coverlen(void){//被覆盖的长度
		return tree[0].len;
	}
	int calc_cf(void);
}X,Y;//x是一系列横线,y是一系列竖线
void SEGMENT_TREE::build(int root,int l,int r){
	now.left=l,now.right=r;
	now.len=0;
	now.count=0;
	if(l<r){
		int mid=(l+r)>>1;
		now.lchild=++tot;
		build(tot,l,mid);
		now.rchild=++tot;
		build(tot,mid+1,r);
	}
	else{
		now.lchild=now.rchild=-1;
	}
}
void SEGMENT_TREE::build(int l,int r){
	build(tot,l,r);
}
void SEGMENT_TREE::update(int root){
	if(now.count) now.len=now.right-now.left+1;
	else{
		if(now.lchild!=-1) now.len=lson.len+rson.len;
		else now.len=0;
	}
}
void SEGMENT_TREE::section_add(int root,int l,int r,int t){
	if(root==-1) return;
	if(now.right<l||now.left>r) return;
	if(now.left>=l&&now.right<=r) now.count+=t;
	else{
		section_add(now.lchild,l,r,t);
		section_add(now.rchild,l,r,t);
	}
	update(root);
}
void SEGMENT_TREE::section_add(int l,int r,int t){
	section_add(0,l,r,t);
}
int SEGMENT_TREE::calc_cf(void){
	int i;
	int ll=0,nl;
	int sum=0;
	for(i=0;i<opt.size();i++){
		int t;
		t=opt[i].type?1:-1;
		section_add(opt[i].l,opt[i].r,t);
		if(i==opt.size()-1||opt[i].pos!=opt[i+1].pos||opt[i].type!=opt[i+1].type){
			nl=coverlen();
			sum+=abs(nl-ll);
			ll=nl;
		}
	}
	return sum;
}
class RECT{
public:
	int x1,x2,y1,y2;//1是小2是大
	void input(void){
		scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
		//x2--,y2--;
	}
};
void init(void){
	X.build(MINC,MAXC);
	Y.build(MINC,MAXC);
	RECT rec[SIZEN];
	int n,i;
	scanf("%d",&n);
	for(i=1;i<=n;i++) rec[i].input();
	ORDER temp;
	for(i=1;i<=n;i++){
		temp.type=1;
		temp.pos=rec[i].y1;
		temp.l=rec[i].x1,temp.r=rec[i].x2-1;
		X.opt.push_back(temp);
		temp.type=0;
		temp.pos=rec[i].y2;
		X.opt.push_back(temp);
	}
	sort(X.opt.begin(),X.opt.end());
	for(i=1;i<=n;i++){
		temp.type=1;
		temp.pos=rec[i].x1;
		temp.l=rec[i].y1,temp.r=rec[i].y2-1;
		Y.opt.push_back(temp);
		temp.type=0;
		temp.pos=rec[i].x2;
		Y.opt.push_back(temp);
	}
	sort(Y.opt.begin(),Y.opt.end());
}
int main(){
	freopen("picture.in","r",stdin);
	freopen("picture.out","w",stdout);
	init();
	printf("%d\n",X.calc_cf()+Y.calc_cf());
	return 0;
}