1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
   | #include <bits/stdc++.h> using namespace std;
  const int iol = 1024 * 1024; char buf[iol], *ioh, *iot, ioc; bool iosig; inline char read() {     if(ioh == iot) {          iot = (ioh = buf) + fread(buf, 1, iol, stdin);          if(ioh == iot) return -1;     }     return *ioh++; } template<class T> inline bool read(T& x) {     iosig = false;     for(ioc = read(); !isdigit(ioc); ioc = read()) {         if(ioc == -1) return false;         if(ioc == '-') iosig = true;     }     x = 0;     while(ioc == '0') ioc = read();     for(; isdigit(ioc); ioc = read())         x = (x << 1) + (x << 3) + (ioc ^ '0');     ioh--;     if(iosig) x = -x;     return true; } struct Node1 {     int t, pos;     inline bool operator < (const Node1 &n) const {         return t > n.t;     } }; struct Node2 {     int d, r, pos;     inline bool operator < (const Node2& n) const {         return d > n.d;     } }; const int MAX = 200005; typedef long long ll; int n, m; Node1 data1[MAX]; Node2 data2[MAX]; struct WeightSegmentTree {          ll *SegmentTreeData1, *SegmentTreeData2;          int size;          void insert(int v, int l, int r, ll d1, ll d2) {                  if (l == r) {             SegmentTreeData1[v] = d2;             SegmentTreeData2[v] = 1;             
              return;         }         register int mid = (l + r) >> 1;         if (d1 <= mid) insert(v << 1, l, mid, d1, d2);         else insert(v << 1 | 1, mid + 1, r, d1, d2);         SegmentTreeData1[v] = SegmentTreeData1[v << 1] + SegmentTreeData1[v << 1 | 1];         SegmentTreeData2[v] = SegmentTreeData2[v << 1] + SegmentTreeData2[v << 1 | 1];     }     ll query(int v, int l, int r, ll d1, ll d2) {         if (l == r) return l;                  register int mid = (l + r) >> 1;         if (SegmentTreeData1[v << 1] - SegmentTreeData2[v << 1] * d2 >= d1)             return query(v << 1, l, mid, d1, d2);         else{                          d1 -= SegmentTreeData1[v << 1] - SegmentTreeData2[v << 1] * d2;             return query(v << 1 | 1, mid + 1, r, d1, d2);         }     }          ll getRootDelta(int d) {         return SegmentTreeData1[1] - SegmentTreeData2[1] * d;     }     WeightSegmentTree(int n) : size(n << 2 | 1), SegmentTreeData1(new ll[n << 2 | 1]), SegmentTreeData2(new ll[n << 2 | 1]) {         memset(SegmentTreeData1, 0, sizeof(ll) * size);         memset(SegmentTreeData2, 0, sizeof(ll) * size);     } } *tree; ll ans[MAX]; int main() {     read(n), read(m);     tree = new WeightSegmentTree(max(n, m) + 1);     for (register int i = 1; i <= m; i++)         read(data1[i].t), data1[i].pos = i;     for (register int i = 1; i <= n; i++)         read(data2[i].d), read(data2[i].r), data2[i].pos = i;     stable_sort(&data1[1], data1 + m + 1), stable_sort(&data2[1], data2 + n + 1);     for (register int i = 1, k = 1; i <= n; i++) {         for (; data1[k].t >= data2[i].d && k <= m; k++)             tree->insert(1, 1, m, data1[k].pos, data1[k].t);                  if (tree->getRootDelta(data2[i].d) < data2[i].r) ans[data2[i].pos] = 0;         else ans[data2[i].pos] = tree->query(1, 1, m, data2[i].r, data2[i].d);     }     for (register int i = 1; i <= n; i++)         cout << ans[i] << " ";     return 0; }
   |