- 开车旅行
- 2015-10-28 21:25:26 @
超时!!!
而且数据范围真的在10^5范围内吗。。。
#include <cstdio>
#include <cstdlib>
#include <map>
#include <cstring>
#include <cctype>
using namespace std;
map<long long, int> Map;
int n, m, x0;
long long h[100005];
int fir[100005], sec[100005];
int g[100001][17];
long long f1[100001][17], f2[100001][17];
int s;
long long x;
long long abs0(long long p) {
if (p > 0)
return p;
else
return -p;
}
long long dist(int a, int b) {
return abs0(h[a] - h[b]);
}
void calcu() {
map<long long, int> ::iterator iter, iter2;
int t[5], cnt;
int p;
for (int i = n; i >= 1; --i) {
memset(t, 0, sizeof (t));
cnt = 0;
Map[h[i]] = i;
iter2 = iter = Map.find(h[i]);
if (iter != Map.begin()) {
--iter;
t[++cnt] = iter->second;
if (iter != Map.begin()) {
--iter;
t[++cnt] = iter->second;
}
}
++iter2;
if (iter2 != Map.end()) {
t[++cnt] = iter2->second;
++iter2;
if (iter2 != Map.end()) {
t[++cnt] = iter2->second;
}
}
for (int j = 1; j <= cnt; ++j) {
if (fir[i] == 0) {
fir[i] = t[j];
p = j;
continue;
}
if (abs0(h[t[j]] - h[i]) < abs0(h[fir[i]] - h[i])) {
fir[i] = t[j];
p = j;
}
else {
if (abs0(h[t[j]] - h[i]) == abs0(h[fir[i]] - h[i]) && h[t[j]] < h[fir[i]]) {
fir[i] = t[j];
p = j;
}
}
}
for (int j = 1; j <= cnt; ++j) {
if (p == j)
continue;
if (sec[i] == 0) {
sec[i] = t[j];
continue;
}
if (abs0(h[t[j]] - h[i]) < abs0(h[sec[i]] - h[i])) {
sec[i] = t[j];
}
else {
if (abs0(h[t[j]] - h[i]) == abs0(h[sec[i]] - h[i]) && h[t[j]] < h[sec[i]]) {
sec[i] = t[j];
}
}
}
}
}
void init() {
for (int i = 1; i <= n; ++i) g[i][0] = sec[i];
for (int i = 1; i <= n; ++i) g[i][1] = fir[g[i][0]];
for (int j = 2; j <= 16; ++j) {
for (int i = 1; i <= n; ++i) {
g[i][j] = g[g[i][j - 1]][j - 1];
}
}
for (int i = 1; i <= n; ++i) if (g[i][0])
f1[i][0] = dist(i, g[i][0]);
for (int i = 1; i <= n; ++i)
f1[i][1] = f1[i][0];
for (int j = 2; j <= 16; ++j) {
for (int i = 1; i <= n; ++i) {
f1[i][j] = f1[i][j - 1] + f1[g[i][j - 1]][j - 1];
}
}
for (int i = 1; i <= n; ++i) if (g[i][0] && g[i][1])
f2[i][1] = dist(g[i][0], g[i][1]);
for (int j = 2; j <= 16; ++j) {
for (int i = 1; i <= n; ++i) {
f2[i][j] = f2[i][j - 1] + f2[g[i][j - 1]][j - 1];
}
}/*
for (int i = 1; i <= n; ++i) {
for (int j = 0; j <= 4; ++j)
printf("<%d, 2^%d>(f1:%d f2:%d)\t", i, j, f1[i][j], f2[i][j]);
printf("\n");
}*/
}
void solve1() {
double ans1 = 1000000000000000000.0;
int ans2 = 0;
for (int i = 1; i <= n; ++i) {
int dista, distb;
dista = distb = 0;
int now = i;
for (int j = 16; j >= 0 && now; --j) {
if (dista + distb + f1[now][j] + f2[now][j] <= x0) {
dista += f1[now][j];
distb += f2[now][j];
now = g[now][j];
}
}
//printf("i:%d %d\n", dista, distb);
if (distb != 0 && dista * 1.0 / distb < ans1) {
ans1 = dista * 1.0 / distb;
ans2 = i;
}
}
printf("%d\n", ans2);
}
void solve2(int i, long long x0) {
int dista, distb;
dista = distb = 0;
int now = i;
for (int j = 16; j >= 0 && now; --j) {
if (dista + distb + f1[now][j] + f2[now][j] <= x0) {
dista += f1[now][j];
distb += f2[now][j];
now = g[now][j];
}
}
printf("%d %d\n", dista, distb);
}
int main(int argc, const char *argv[]) {
freopen("drive.in", "r", stdin);
freopen("drive.ans", "w", stdout);
scanf("%d", &n);
for (int i = 1; i <= n; ++i)
scanf("%I64d", &h[i]);
calcu();
init();
scanf("%d%d", &x0, &m);
solve1();
for (int i = 1; i <= m; ++i) {
scanf("%d %I64d", &s, &x);
solve2(s, x);
}
return 0;
}
2 条评论
-
Antman LV 9 @ 2016-02-15 15:30:59
.
-
2015-10-28 21:25:52@
忽略文件输入输出
- 1