EntropyIncreaser

NOIP2012 开车旅行

Dec 6th, 2017
184
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.05 KB | None | 0 0
  1. #include <cstdio>
  2.  
  3. #include <map>
  4.  
  5. #define LOG(FMT...) // fprintf(stderr, FMT)
  6.  
  7. using namespace std;
  8.  
  9. typedef long long ll;
  10. typedef map<int, int> map_t;
  11. typedef map_t::iterator iter_t;
  12.  
  13. const int N = 100010, LOGN = 20;
  14.  
  15. int n, m, x0, ans;
  16. ll da, db, xa = 1000000000, xb;
  17. int h[N], s[N], x[N];
  18. int jump[N << 1][LOGN];
  19. ll dist_a[N << 1][LOGN], dist_b[N << 1][LOGN];
  20. map_t mp;
  21.  
  22. ll iabs(ll x);
  23. iter_t nearest(iter_t it1, iter_t it2, int x);
  24. void calc_dist(int s, int x);
  25.  
  26. int main() {
  27.     scanf("%d", &n);
  28.     for (int i = 1; i <= n; ++i)
  29.         scanf("%d", &h[i]);
  30.     mp.insert(make_pair(h[n], n));
  31.     mp.insert(make_pair(h[n - 1], n - 1));
  32.     jump[((n - 1) << 1) | 1][0] = n << 1;
  33.     dist_b[((n - 1) << 1) | 1][0] = iabs(h[n] - h[n - 1]);
  34.     for (int i = n - 2; i; --i) {
  35.         iter_t it = mp.insert(make_pair(h[i], i)).first, prv, nxt;
  36.         prv = it;
  37.         if (prv == mp.begin())
  38.             prv = mp.end();
  39.         else
  40.             --prv;
  41.         nxt = it;
  42.         ++nxt;
  43.         int k = i << 1;
  44.         if (nearest(prv, nxt, h[i]) == prv) {
  45.             jump[k | 1][0] = prv->second << 1;
  46.             LOG("%d->%d ", i, prv->second);
  47.             dist_b[k | 1][0] = iabs(prv->first - h[i]);
  48.             if (prv == mp.begin())
  49.                 prv = mp.end();
  50.             else
  51.                 --prv;
  52.         } else {
  53.             jump[k | 1][0] = nxt->second << 1;
  54.             LOG("%d->%d ", i, nxt->second);
  55.             dist_b[k | 1][0] = iabs(nxt->first - h[i]);
  56.             if (nxt != mp.end())
  57.                 ++nxt;
  58.         }
  59.         LOG("%d\n", prv == mp.end());
  60.         if (nearest(prv, nxt, h[i]) == prv) {
  61.             jump[k][0] = (prv->second << 1) | 1;
  62.             LOG("%d\n", prv->second);
  63.             dist_a[k][0] = iabs(prv->first - h[i]);
  64.         } else {
  65.             jump[k][0] = (nxt->second << 1) | 1;
  66.             LOG("%d\n", nxt->second);
  67.             dist_a[k][0] = iabs(nxt->first - h[i]);
  68.         }
  69.         LOG("FINE %d\n", i);
  70.     }
  71.     for (int i = n; i; --i)
  72.         for (int k = i << 1; k <= ((i << 1) | 1); ++k)
  73.             for (int j = 1; j < LOGN; ++j) {
  74.                 jump[k][j] = jump[jump[k][j - 1]][j - 1];
  75.                 dist_a[k][j] = dist_a[k][j - 1] + dist_a[jump[k][j - 1]][j - 1];
  76.                 dist_b[k][j] = dist_b[k][j - 1] + dist_b[jump[k][j - 1]][j - 1];
  77.             }
  78.     scanf("%d%d", &x0, &m);
  79.     for (int i = 1; i <= m; ++i)
  80.         scanf("%d%d", &s[i], &x[i]);
  81.     for (int i = 1; i <= n; ++i) {
  82.         calc_dist(i, x0);
  83.         if (db == 0) {
  84.             if (xb == 0 && h[ans] < h[i]) {
  85.                 xa = da;
  86.                 ans = i;
  87.             }
  88.         } else if ((ll)da * xb < (ll)xa * db || ((ll)da * xb == (ll)xa * db && h[ans] < h[i])) {
  89.             ans = i;
  90.             xa = da;
  91.             xb = db;
  92.             LOG("NEW %d\n", i);
  93.         }
  94.     }
  95.     LOG("%lld %lld\n", xa, xb);
  96.     printf("%d\n", ans);
  97.     for (int i = 1; i <= m; ++i) {
  98.         calc_dist(s[i], x[i]);
  99.         printf("%lld %lld\n", da, db);
  100.     }
  101.     return 0;
  102. }
  103.  
  104. inline void calc_dist(int s, int x) {
  105.     da = db = 0;
  106.     s <<= 1;
  107.     for (int j = LOGN - 1; ~j; --j)
  108.         if (dist_a[s][j] + dist_b[s][j] + da + db <= x) {
  109.             da += dist_a[s][j];
  110.             db += dist_b[s][j];
  111.             s = jump[s][j];
  112.         }
  113. }
  114.  
  115. inline ll iabs(ll x)
  116. { return x < 0 ? -x : x; }
  117.  
  118. inline iter_t nearest(iter_t it1, iter_t it2, int x) {
  119.     if (it1->first == x || it1 == mp.end())
  120.         return it2;
  121.     if (it2->first == x || it2 == mp.end())
  122.         return it1;
  123.     if (iabs(it1->first - x) <= iabs(it2->first - x))
  124.         return it1;
  125.     return it2;
  126. }
Advertisement
Add Comment
Please, Sign In to add comment