来源:http://codeforces.com/contest/702/problem/F
参考思路:
具体实现:
/**********************
http://codeforces.com/contest/702/problem/F
***********************/
#include
#include
#include
using namespace std;
#define MAX 200000
typedef pair
shirt;
int n, k, ans[MAX];
shirt s[MAX];
mt19937 ran(520);
struct Treap
{
Treap *l, *r;
int id, money, cnt, fix, dc, dm;
Treap(int _id, int _money)
{
id = _id; money = _money;
cnt = dc = dm = 0;
l = r = NULL;
fix = ran();
}
void apply(int c, int m)
{
dc = c;
dm = m;
money -= m;
cnt += c;
}
void down()
{
if (dc)
{
if (l) l->cnt += dc, l->dc += dc;
if (r) r->cnt += dc, r->dc += dc;
dc = 0;
}
if (dm)
{
if (l) l->money -= dm, l->dm += dm;
if (r) r->money -= dm, r->dm += dm;
dm = 0;
}
}
}*root;
typedef pair
Droot; Treap* merge(Treap *a, Treap *b) { if (!a) return b; if (!b) return a; if (a->fix < b->fix) { a->down(); a->r = merge(a->r, b); return a; } else { b->down(); b->l = merge(a, b->l); return b; } } Droot split(Treap *x, int mny) { if (!x) return Droot(NULL, NULL); Droot t; x->down(); if (x->money < mny) { t = split(x->r, mny); x->r = t.first; t.first = x; } else { t = split(x->l, mny); x->l = t.second; t.second = x; } return t; } Treap* insert(Treap *x, Treap *n) { Droot t = split(x, n->money); x = merge(merge(t.first, n), t.second); return x; } int getMax(Treap *x) { //x not null while (x->r) { x->down(); x = x->r; } return x->money; } int getMin(Treap *x) { if (!x) return -1; while (x->l) { x->down(); x = x->l; } return x->money; } void inorder(Treap *x) { if (!x) return; x->down(); inorder(x->l); ans[x->id] = x->cnt; inorder(x->r); } void init() { cin >> n; for (int i = 0; i < n; ++i) { cin >> s[i].second >> s[i].first; s[i].first *= -1; } sort(s, s + n); int b; cin >> k; for (int i = 0; i < k; ++i) { cin >> b; Treap *t = new Treap(i, b); if (root) root = insert(root, t); else root = t; } } void solve() { Droot t, p; int lmax, rmin; for (int i = 0; i < n; ++i) { t = split(root, s[i].second); if (!t.second) continue; t.second->apply(1, s[i].second); if (!t.first) continue; lmax = getMax(t.first); rmin = getMin(t.second); while (lmax > rmin && rmin >= 0) { p = split(t.second, rmin + 1); t.first = insert(t.first, p.first); t.second = p.second; rmin = getMin(t.second); } root = merge(t.first, t.second); } inorder(root); for (int i = 0; i < k; ++i) { cout << ans[i]; if (i == k - 1) cout << endl; else cout << " "; } } int main() { init(); solve(); return 0; }