记录编号 303598 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [NOIP 2012]开车旅行 最终得分 100
用户昵称 GravatarFmuckss 是否通过 通过
代码语言 C++ 运行时间 3.602 s
提交时间 2016-09-06 08:03:07 内存使用 43.96 MiB
显示代码纯文本
  1. #include <iostream>
  2. #include <cstdio>
  3. #include <set>
  4. #include <cmath>
  5. using namespace std;
  6. typedef long long LL;
  7. const int maxn = 1e5 + 10;
  8. const int inf = 2e9;
  9. const double eps = 1e-7;
  10.  
  11. #define A (1)
  12. #define B (0)
  13.  
  14. int n, m;
  15. int to_end, end_pos;
  16. int x0;
  17.  
  18. #define is_num(x) (x <= '9' and x >= '0')
  19. int get_num() {
  20. char tmp = getchar();
  21. int res = 0;
  22. bool mul = false;
  23. while(not is_num(tmp)) { if(tmp == '-') mul = true; tmp = getchar(); }
  24. while( is_num(tmp)) {
  25. res = res * 10 + tmp - '0';
  26. tmp = getchar();
  27. }
  28. return mul ? -res : res;
  29. }
  30.  
  31. int to_ne[2][maxn];
  32. int to_v[2][maxn];
  33.  
  34. int mul_to[maxn][20];
  35. LL disa[maxn][20];
  36. LL disb[maxn][20];
  37.  
  38. inline void add_edge(int fr, int to, int v, int type) {
  39. to_ne[type][fr] = to;
  40. to_v[type][fr] = v;
  41. }
  42.  
  43. class Node {
  44. public:
  45. int pos;
  46. LL hi;
  47. Node() {}
  48. Node(int pos_, int hi_) { pos = pos_, hi = (LL)hi_; }
  49. bool operator < (const Node &b) const{
  50. return hi == b.hi ? pos < b.pos : hi < b.hi;
  51. }
  52. void print() {
  53. printf("%d %lld\n", pos, hi);
  54. }
  55. }ns[maxn];
  56.  
  57. set<Node> s;
  58.  
  59. inline int get_min(int i) {
  60. set<Node> :: iterator now;
  61. Node la, ne, del;
  62. now = s.find(ns[i]);
  63. // out_s();
  64. // printf("\n");
  65. if(now != s.begin()) {
  66. now--;
  67. la = *(now);
  68. now = s.lower_bound(Node(0, la.hi));
  69. la = *(now);
  70. } else {
  71. la = Node(inf, inf);
  72. }
  73.  
  74. now = s.upper_bound(ns[i]);
  75. if(now != s.end()) ne = *(now);
  76. else ne = Node(inf, inf);
  77. if(abs(ns[i].hi - la.hi) <= abs(ne.hi - ns[i].hi)) return la.pos;
  78. else return ne.pos;
  79. }
  80.  
  81. inline void build() {
  82. int del, pos;
  83. for(int i = 1; i <= n - 2; i++) {
  84. pos = get_min(i);
  85. if(pos != inf) add_edge(i, pos, abs(ns[i].hi - ns[pos].hi), B);
  86. if(pos != inf) s.erase(s.find(ns[pos]));
  87. del = pos;
  88. pos = get_min(i);
  89. if(pos != inf) add_edge(i, pos, abs(ns[i].hi - ns[pos].hi), A);
  90. if(pos != inf) s.insert(ns[del]);
  91. s.erase(ns[i]);
  92. }
  93. add_edge(n - 1, n, abs(ns[n - 1].hi - ns[n].hi), B);
  94. }
  95.  
  96.  
  97. LL da, db;
  98. int ans_tar;
  99. LL ans_a, ans_b, ans_hi;
  100.  
  101. void read() {
  102. n = get_num();
  103. int x, hi;
  104. for(int i = 1; i <= n; i++) {
  105. hi = get_num();
  106. ns[i] = Node(i, hi);
  107. s.insert(ns[i]);
  108. }
  109. x0 = get_num();
  110. }
  111.  
  112. inline void get_ne() {
  113. for(int i = 1; i <= n; i++) {
  114. mul_to[i][0] = to_ne[B][to_ne[A][i]]; // target which start with A end by two step
  115. disa[i][0] = to_v[A][i]; // the dis of driver a
  116. disb[i][0] = to_v[B][to_ne[A][i]]; // the dis of driver b
  117. }
  118. for(int j = 1; j <= 17; j++) {
  119. for(int i = 1; i <= n; i++) {
  120. mul_to[i][j] = mul_to[mul_to[i][j - 1]][j - 1];
  121. disa[i][j] = disa[i][j - 1] + disa[mul_to[i][j - 1]][j - 1];
  122. disb[i][j] = disb[i][j - 1] + disb[mul_to[i][j - 1]][j - 1];
  123. }
  124. }
  125. }
  126.  
  127. void query(int s, int lim, LL &da, LL &db) {
  128. for(int i = 17; i >= 0; i--) {
  129. if(disa[s][i] + disb[s][i] > lim) continue;
  130. lim -= disa[s][i] + disb[s][i];
  131. da += disa[s][i];
  132. db += disb[s][i];
  133. s = mul_to[s][i];
  134. }
  135. if(to_v[A][s] <= lim) da += to_v[A][s];
  136. }
  137.  
  138. void solve() {
  139. build();
  140. // out();
  141. get_ne();
  142. ans_a = 1;
  143. for(int i = 1; i <= n; i++) {
  144. da = 0, db = 0;
  145. query(i, x0, da, db);
  146. if(db == 0) da = inf;
  147. if(da * ans_b < db * ans_a)
  148. ans_a = da, ans_b = db, ans_tar = i, ans_hi = ns[i].hi;
  149. else if(da * ans_b == db * ans_a and ans_hi < ns[i].hi)
  150. ans_a = da, ans_b = db, ans_tar = i, ans_hi = ns[i].hi;
  151.  
  152. }
  153. printf("%d\n", ans_tar);
  154. m = get_num();
  155. int x, hi;
  156. for(int i = 1; i <= m; i++) {
  157. x = get_num();
  158. hi = get_num();
  159. da = db = 0;
  160. query(x, hi, da, db);
  161. printf("%lld %lld\n", da, db);
  162. }
  163. }
  164.  
  165. int main() {
  166. freopen("drive.in", "r", stdin);
  167. freopen("drive.out", "w", stdout);
  168. read();
  169. solve();
  170. return 0;
  171. }