Advertisement
Guest User

Untitled

a guest
Jun 19th, 2016
162
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.34 KB | None | 0 0
  1. #include <iostream>
  2. #include <algorithm>
  3.  
  4. using namespace std;
  5.  
  6. const int INF = 1000 * 1000 * 1000 + 5;
  7.  
  8. struct NodeSum {
  9.     long long val;
  10.     NodeSum *l, *r;
  11.  
  12.     NodeSum(long long _val): val(_val), l(0), r(0) {}
  13.  
  14.     NodeSum(NodeSum *_l, NodeSum *_r):
  15.         val((_l? _l->val : 0) + (_r? _r->val : 0)), l(_l), r(_r) {}
  16. };
  17.  
  18. struct NodeMin {
  19.     int val;
  20.     NodeMin *l, *r;
  21.  
  22.     NodeMin(int _val): val(_val), l(0), r(0) {}
  23.  
  24.     NodeMin(NodeMin *_l, NodeMin *_r):
  25.         val(min((_l? _l->val : INF), (_r? _r->val : INF))), l(_l), r(_r) {}
  26. };
  27.  
  28. const int MAXN = 150 * 1000 + 5;
  29. int a[MAXN];
  30. pair<int, int> p[MAXN];
  31. NodeSum *stsum[MAXN];
  32. NodeMin *stmin[MAXN];
  33.  
  34. NodeSum *buildstsum() {
  35.     NodeSum *res = new NodeSum(0);
  36.     for(int i = 0; i < 20; i++)
  37.         res = new NodeSum(res, res);
  38.     return res;
  39. }
  40.  
  41. NodeSum *update(NodeSum *v, int tl, int tr, int pos, int val) {
  42.     if(tl == tr - 1)
  43.         return new NodeSum(val);
  44.     int tm = (tl + tr) / 2;
  45.     if(pos < tm)
  46.         return new NodeSum(update(v->l, tl, tm, pos, val), v->r);
  47.     else
  48.         return new NodeSum(v->l, update(v->r, tm, tr, pos, val));
  49. }
  50.  
  51. long long get(NodeSum *v, int tl, int tr, int l, int r) {
  52.     if(tl == l && tr == r)
  53.         return v->val;
  54.     int tm = (tl + tr) / 2;
  55.     long long res = 0;
  56.     if(l < tm)
  57.         res += get(v->l, tl, tm, l, min(r, tm));
  58.     if(r > tm)
  59.         res += get(v->r, tm, tr, max(l, tm), r);
  60.     return res;
  61. }
  62.  
  63. NodeMin *buildstmin() {
  64.     NodeMin *res = new NodeMin(INF);
  65.     for(int i = 0; i < 20; i++)
  66.         res = new NodeMin(res, res);
  67.     return res;
  68. }
  69.  
  70. NodeMin *update(NodeMin *v, int tl, int tr, int pos, int val) {
  71.     if(tl == tr - 1)
  72.         return new NodeMin(val);
  73.     int tm = (tl + tr) / 2;
  74.     if(pos < tm)
  75.         return new NodeMin(update(v->l, tl, tm, pos, val), v->r);
  76.     else
  77.         return new NodeMin(v->l, update(v->r, tm, tr, pos, val));
  78. }
  79.  
  80. int get(NodeMin *v, int tl, int tr, int l, int r) {
  81.     if(tl == l && tr == r)
  82.         return v->val;
  83.     int tm = (tl + tr) / 2, res = INF;
  84.     if(l < tm)
  85.         res = min(res, get(v->l, tl, tm, l, min(r, tm)));
  86.     if(r > tm)
  87.         res = min(res, get(v->r, tm, tr, max(l, tm), r));
  88.     return res;
  89. }
  90.  
  91. int main() {
  92.     ios_base::sync_with_stdio(false);
  93.     cin.tie(0);
  94.     int n, m;
  95.     cin >> n >> m;
  96.     for(int i = 0; i < n; i++) {
  97.         cin >> a[i];
  98.         p[i] = make_pair(a[i], i);
  99.     }
  100.     sort(p, p + n);
  101.     stsum[0] = buildstsum();
  102.     for(int i = 0; i < n; i++)
  103.         stsum[i + 1] = update(stsum[i], 0, n, p[i].second, p[i].first);
  104.     stmin[n] = buildstmin();
  105.     for(int i = n - 1; i >= 0; i--)
  106.         stmin[i] = update(stmin[i + 1], 0, n, p[i].second, p[i].first);
  107.     for(int i = 0; i < m; i++) {
  108.         int l, r;
  109.         cin >> l >> r;
  110.         l--;
  111.         long long s = 1;
  112.         while(true) {
  113.             int x;
  114.             if(s > INF)
  115.                 x = INF;
  116.             else {
  117.                 x = lower_bound(p, p + n, make_pair((int)s, 0)) - p;
  118.                 x = get(stmin[x], 0, n, l, r);
  119.             }
  120.             int pp = lower_bound(p, p + n, make_pair(x, 0)) - p;
  121.             s = get(stsum[pp], 0, n, l, r) + 1;
  122.             if(x > s || x == INF) {
  123.                 cout << s << '\n';
  124.                 break;
  125.             }
  126.             s += x;
  127.         }
  128.     }
  129.     return 0;
  130. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement