记录编号 303598 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [NOIP 2012]开车旅行 最终得分 100
用户昵称 GravatarFmuckss 是否通过 通过
代码语言 C++ 运行时间 3.602 s
提交时间 2016-09-06 08:03:07 内存使用 43.96 MiB
显示代码纯文本
#include <iostream>
#include <cstdio>
#include <set>
#include <cmath>
using namespace std;
typedef long long LL;
const int maxn = 1e5 + 10;
const int inf = 2e9;
const double eps = 1e-7;

#define A (1)
#define B (0)

int n, m;
int to_end, end_pos;
int x0;

#define is_num(x) (x <= '9' and x >= '0')
int get_num() {
	char tmp = getchar();
	int res = 0;
	bool mul = false;
	while(not is_num(tmp)) { if(tmp == '-') mul = true; tmp = getchar(); }
	while(    is_num(tmp)) {
		res = res * 10 + tmp - '0';
		tmp = getchar();
	}
	return mul ? -res : res;
}

int to_ne[2][maxn];
int to_v[2][maxn];

int mul_to[maxn][20];
LL disa[maxn][20];
LL disb[maxn][20]; 

inline void add_edge(int fr, int to, int v, int type) {
	to_ne[type][fr] = to;
	to_v[type][fr] = v;
}

class Node {
public:
	int pos;
	LL hi;
	Node() {}
	Node(int pos_, int hi_) { pos = pos_, hi = (LL)hi_; }
	
	bool operator < (const Node &b) const{
		return hi == b.hi ? pos < b.pos : hi < b.hi; 
	}
	void print() {
		printf("%d %lld\n", pos, hi);
	}
}ns[maxn];

set<Node> s;

inline int get_min(int i) {
	set<Node> :: iterator now;
	Node la, ne, del;
	now = s.find(ns[i]);
	// out_s();
	// printf("\n");
	if(now != s.begin()) {
		now--;
		la = *(now);
		now = s.lower_bound(Node(0, la.hi));
		la = *(now);
	} else {
		la = Node(inf, inf);
	}

	now = s.upper_bound(ns[i]);
	if(now != s.end()) ne = *(now);
	else ne = Node(inf, inf);
	
	if(abs(ns[i].hi - la.hi) <= abs(ne.hi - ns[i].hi)) return la.pos;
	else return ne.pos;
}

inline void build() {
	int del, pos;
	for(int i = 1; i <= n - 2; i++) {
		pos = get_min(i);
		if(pos != inf) add_edge(i, pos, abs(ns[i].hi - ns[pos].hi), B);
		
		if(pos != inf) s.erase(s.find(ns[pos]));
		del = pos;
		
		pos = get_min(i);
		if(pos != inf) add_edge(i, pos, abs(ns[i].hi - ns[pos].hi), A);
		
		if(pos != inf) s.insert(ns[del]);
		s.erase(ns[i]);
	}
	
	add_edge(n - 1, n, abs(ns[n - 1].hi - ns[n].hi), B);
}


LL da, db;
int ans_tar;
LL ans_a, ans_b, ans_hi; 

void read() {
	n = get_num();
	int x, hi;
	for(int i = 1; i <= n; i++) {
		hi = get_num();
		ns[i] = Node(i, hi);
				
		s.insert(ns[i]);
	}
	x0 = get_num();
}

inline void get_ne() {
	for(int i = 1; i <= n; i++) {
		mul_to[i][0] = to_ne[B][to_ne[A][i]]; // target which start with A end by two step
		
		disa[i][0] = to_v[A][i]; // the dis of driver a 
		disb[i][0] = to_v[B][to_ne[A][i]]; // the dis of driver b 
	}
	
	for(int j = 1; j <= 17; j++) {
		for(int i = 1; i <= n; i++) {
			mul_to[i][j] = mul_to[mul_to[i][j - 1]][j - 1];
			
			disa[i][j] = disa[i][j - 1] + disa[mul_to[i][j - 1]][j - 1];
			disb[i][j] = disb[i][j - 1] + disb[mul_to[i][j - 1]][j - 1];
		}
	}
}

void query(int s, int lim, LL &da, LL &db) {
	for(int i = 17; i >= 0; i--) {
		if(disa[s][i] + disb[s][i] > lim) continue;
		lim -= disa[s][i] + disb[s][i];
		
		da += disa[s][i];
		db += disb[s][i];
		
		s = mul_to[s][i];
	}
	
	if(to_v[A][s] <= lim) da += to_v[A][s];
}

void solve() {
	build();
	// out();
	get_ne();
	ans_a = 1;
	
	for(int i = 1; i <= n; i++) {
		da = 0, db = 0;
		query(i, x0, da, db);
		
		if(db == 0) da = inf;
		
		if(da * ans_b < db * ans_a)
			ans_a = da, ans_b = db, ans_tar = i, ans_hi = ns[i].hi;
		else if(da * ans_b == db * ans_a and ans_hi < ns[i].hi) 
			ans_a = da, ans_b = db, ans_tar = i, ans_hi = ns[i].hi;

	}
	
	printf("%d\n", ans_tar);
	
	m = get_num();
	int x, hi;
	for(int i = 1; i <= m; i++) {
		x = get_num();
		hi = get_num();
		
		da = db = 0;
		query(x, hi, da, db);
		printf("%lld %lld\n", da, db);
	}
}

int main() {
	freopen("drive.in", "r", stdin);
	freopen("drive.out", "w", stdout);
	read();
	solve();
	return 0;
}