记录编号 241422 评测结果 AAAAAAAAAA
题目名称 [HAOI 2011]防线修建 最终得分 100
用户昵称 GravatarFmuckss 是否通过 通过
代码语言 C++ 运行时间 0.261 s
提交时间 2016-03-25 11:58:04 内存使用 27.02 MiB
显示代码纯文本
#include<iostream>
#include<cstdio>
#include<set>
#include<cmath>
using namespace std;
const int maxn = 1e6+10;
int n, m, q;
int del[maxn];

inline int get_num() {
	int ans = 0;
	char tmp = getchar();
	while(tmp < '0' || tmp > '9') tmp = getchar();
	while(tmp <= '9' && tmp >= '0') {
		ans = ans*10 + tmp - '0';
		tmp = getchar();
	}
	return ans;
}

struct question {
	bool ques;
	int tar;
	double ans;
	question() {}
	question(bool is_, int tar_) { ques = is_, tar = tar_; }
}qs[maxn];


struct node {
	int x, y;
	node() {}
	node(int x_, int y_) { x = x_, y = y_; }
	inline bool operator < (const node &b) const {
		return x == b.x ? y < b.y : x < b.x;
	} 
	inline node operator - (const node &b) const{//得到a->b的node向量 
		return node(b.x-x, b.y-y);
	}
	inline int operator * (const node &b) const{
		return x*b.y - y*b.x;
	} 
}ns[maxn];


class Convex_hull {
private:
	set<node> ns;
	double tot;
public:
	inline void init(int x, int y) {
		ns.insert(node(0, 0));
		ns.insert(node(n, 0));
		ns.insert(node(x, y));
		tot = dis(node(x, y), node(0, 0)) + dis(node(x, y), node(n, 0));
	}
	inline double dis(node a, node b) {
		return sqrt((double)((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)));
	}
	inline void rebuild(set<node>::iterator tar) {
		set<node>::iterator it = tar;
		it--;
		node l = *(it);//当前连接节点 
		while(it != ns.begin()) {
			it--;
			node ne = *(it);//下一个节点
			if((l - *tar) * (ne - *tar) > 0) break; //到下一个点的连线在凸包内部,更新左节点结束 
			tot -= dis(l, ne);
			ns.erase(l);
			l = ne;
		}
		it = tar;
		it++; 
		node r = *(it);//当前连接节点 
		set<node>::iterator end = ns.end();
		end--; 
		while(it != end) {
			it++;
			node ne = *(it);//下一个节点
			if((r - *tar) * (ne - *tar) < 0) break; //到下一个点的连线在凸包内部,更新左节点结束 
			tot -= dis(r, ne);
			ns.erase(r);
			r = ne;
		}
		tot += dis(*tar, l) + dis(*tar, r);
	}
	inline void insert(node tar) {
		ns.insert(tar);
		set<node>::iterator it;
		it = ns.find(tar);
		it--;
		node l = *(it);
		it++, it++;
		node r = *(it);
		if((r - l) * (tar - l) < 0) {//如果在凸包内部则不需要更新 
			ns.erase(tar);
			return;
		}
		tot -= dis(l, r);
		it--;
		rebuild(it); 
	}
	inline double now_ans() {
		return tot;
	}
}ch; 


inline void read() {
	int x, y;
	n = get_num();
	x = get_num();
	y = get_num();
	m = get_num();
	ch.init(x, y);
	for(int i = 1; i <= m; i++) {
		x = get_num();
		y = get_num();
		ns[i] = node(x, y);
	}
	q = get_num();
	int is;
	for(int i = 1; i <= q; i++) {
		is = get_num();
		if(is == 2) {
			qs[i] = question(1, 0);
		} else {
			x = get_num();
			qs[i] = question(0, x);
			del[x] = true;
		}
	} 
} 


inline void solve() {
	for(int i = 1; i <= m; i++) {
		if(del[i]) continue;
		ch.insert(ns[i]);
	}
	for(int i = q; i >= 1; i--) {//倒叙后加点 
		if(qs[i].ques) qs[i].ans = ch.now_ans();
		else {
			ch.insert(ns[qs[i].tar]);
		}
	}
	for(int i = 1; i <= q; i++) {//正序输出 
		if(qs[i].ques) printf("%.2lf\n", qs[i].ans);
	}
}
int main() {
	freopen("defense.in", "r", stdin);
	freopen("defense.out", "w", stdout);
	read();
	solve();
	return 0;
}