T_Shirts

来源: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; } 
       
      
      
     
     
    
    
   
   



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值