记录编号 |
303598 |
评测结果 |
AAAAAAAAAAAAAAAAAAAA |
题目名称 |
[NOIP 2012]开车旅行 |
最终得分 |
100 |
用户昵称 |
Fmuckss |
是否通过 |
通过 |
代码语言 |
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;
}