@description@

有 n 件 T-shirt,第 i 件 T-shirt 有一个 ci 和 qi,分别表示费用与质量。

同时有 k 个顾客,第 j 个顾客准备了 bj 的金钱去购买 T-shirt。

每个顾客的购买策略是相同的:

他会买他的资金范围内 q 值最大的一件,如果有多个选 c 最小的一件,每种 T-shirt 只买1 次。

重复购买,直到所有的 T-shirt 他都买不起或者他都买过了。

求每位顾客最终可以购买的 T-shirt 数量。

Input

第一行一个整数 n (1 ≤ n ≤ 2·10^5),表示 T-shirt 的种类数。

接下来 n 行,每行两个整数 ci 与 qi (1 ≤ ci, qi ≤ 10^9),含义如上。

接下来一行一个正整数 k (1 ≤ k ≤ 2·10^5) ,表示顾客数。

接下来 k 个正整数 b1, b2, ..., bk (1 ≤ bj ≤ 10^9)。

Output

输出一行 k 个整数,表示第 i 个人买的 T-shirt。

Examples

Input

3

7 5

3 5

4 3

2

13 14

Output

2 3

Input

2

100 500

50 499

4

50 200 150 100

Output

1 2 2 1

@solution@

假如我们把人当作询问,T-shirt 当作元素,则至少我是想不出什么办法快速维护求出询问的。

但是反过来——我们按照 T-shirt 的优先级从大到小排序,把每个 T-shirt 当作一次修改,然后对人进行统一地修改,就很有戏了。

假如一个 T-shirt 的价格是 c,则我们的修改步骤就是先找出 >= c 的人,将这些人所拥有的钱减去 c,将这些人所拥有的 T-shirt 数量加上 1。

貌似可以用平衡树来 merge 和 split。但是注意,我们只能 merge 两个值域没有交集的平衡树,而减去 c 过后可能就产生了交集。

我们将 >= c 的人分为两类。第一类是 >= 2*c 的,这一部分减去 c 依然可以直接 merge;第二类是 < 2*c 的,这一类减去 c 过后只能一个个暴力插入。

因为第二类的人一定满足 c <= x < 2*c,每一次 x 至少折半,这样每个人只会被暴力插入 O(log)

于是就 O(nlog^2n) 的总复杂度。因为是 codeforces 所以能过。

@accepted code@

#include<cstdlib>
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
const int MAXN = 200000;
struct treap{
struct node{
node *ch[2];
int key, tg1;
int sum, tg2;
unsigned int pri;
}pl[MAXN + 5], *ncnt, *NIL;
#define mp make_pair
#define fi first
#define se second
typedef pair<node*, node*> Droot;
unsigned int get_rand() {return (rand() << 16) | rand();}
treap() {
NIL = ncnt = &pl[0];
NIL->ch[0] = NIL->ch[1] = NIL;
NIL->key = NIL->tg1 = NIL->sum = NIL->tg2 = 0;
NIL->pri = -1;
}
node *newnode(int k) {
node *p = (++ncnt);
p->ch[0] = p->ch[1] = NIL;
p->key = k, p->tg1 = p->sum = p->tg2 = 0;
p->pri = get_rand();
return p;
}
void maintain1(node *x, int k) {if( x != NIL ) x->key += k, x->tg1 += k;}
void maintain2(node *x, int k) {if( x != NIL ) x->sum += k, x->tg2 += k;}
void pushdown(node *rt) {
if( rt->tg1 ) {
maintain1(rt->ch[0], rt->tg1), maintain1(rt->ch[1], rt->tg1);
rt->tg1 = 0;
}
if( rt->tg2 ) {
maintain2(rt->ch[0], rt->tg2), maintain2(rt->ch[1], rt->tg2);
rt->tg2 = 0;
}
}
node *merge(node *x, node *y) {
if( x == NIL ) return y;
if( y == NIL ) return x;
pushdown(x), pushdown(y);
if( x->pri < y->pri ) {
x->ch[1] = merge(x->ch[1], y);
return x;
}
else {
y->ch[0] = merge(x, y->ch[0]);
return y;
}
}
Droot split(node *rt, int k) {
if( rt == NIL ) return mp(NIL, NIL);
pushdown(rt);
if( rt->key < k ) {
Droot p = split(rt->ch[1], k);
rt->ch[1] = p.fi; return mp(rt, p.se);
}
else {
Droot p = split(rt->ch[0], k);
rt->ch[0] = p.se; return mp(p.fi, rt);
}
}// < k, >= k
node *insert(node *rt, node *x) {
Droot p = split(rt, x->key);
return merge(p.fi, merge(x, p.se));
}
void push(node *&rt, node *x) {
if( x == NIL ) return ;
pushdown(x);
push(rt, x->ch[0]), push(rt, x->ch[1]);
x->ch[0] = x->ch[1] = NIL;
rt = insert(rt, x);
}
node *update(node *rt, int k) {
Droot p = split(rt, k);
if( p.se == NIL ) return merge(p.fi, p.se);
p.se->key -= k, p.se->tg1 -= k;
p.se->sum += 1, p.se->tg2 += 1;
Droot q = split(p.se, k);
if( q.fi != NIL ) push(p.fi, q.fi);
return merge(p.fi, q.se);
}
void dfs(node *x) {
if( x == NIL ) return ;
pushdown(x);
dfs(x->ch[0]), dfs(x->ch[1]);
}
}T;
treap::node *nd[MAXN + 5], *rt;
struct Tshirt{
int c, q;
Tshirt(int _c=0, int _q=0):c(_c), q(_q) {}
friend bool operator < (Tshirt a, Tshirt b) {
return (a.q == b.q) ? a.c < b.c : a.q > b.q;
}
}t[MAXN + 5];
int ans[MAXN + 5];
int read() {
int x = 0; char ch = getchar();
while( ch > '9' || ch < '0' ) ch = getchar();
while( '0' <= ch && ch <= '9' ) x = 10*x + ch - '0', ch = getchar();
return x;
}
int main() {
int n = read(), k;
srand(n ^ 0307);
for(int i=1;i<=n;i++)
t[i].c = read(), t[i].q = read();
sort(t + 1, t + n + 1);
k = read(), rt = T.NIL;
for(int i=1;i<=k;i++)
rt = T.insert(rt, nd[i] = T.newnode(read()));
for(int i=1;i<=n;i++)
rt = T.update(rt, t[i].c);
T.dfs(rt);
for(int i=1;i<=k;i++)
printf("%d ", nd[i]->sum);
}

@details@

思路本身还是很巧妙的。

而且也印证了非旋 treap 是一种非常优美的数据结构,因为基本上没有什么实现难度。

@codeforces - 702F@ T-Shirts的更多相关文章

  1. Codeforces 702F - T-shirts(平衡树+势能分析)

    题面传送门 首先肯定将所有物品排个序. 考虑暴力做法,对于每个询问,枚举所有物品,能买就买.不过扫一眼就知道无法直接优化. 不妨换个角度,暴力做法是枚举询问,这次我们枚举物品.从左到右依次枚举所有物品 ...

  2. python爬虫学习(5) —— 扒一下codeforces题面

    上一次我们拿学校的URP做了个小小的demo.... 其实我们还可以把每个学生的证件照爬下来做成一个证件照校花校草评比 另外也可以写一个物理实验自动选课... 但是出于多种原因,,还是绕开这些敏感话题 ...

  3. 【Codeforces 738D】Sea Battle(贪心)

    http://codeforces.com/contest/738/problem/D Galya is playing one-dimensional Sea Battle on a 1 × n g ...

  4. 【Codeforces 738C】Road to Cinema

    http://codeforces.com/contest/738/problem/C Vasya is currently at a car rental service, and he wants ...

  5. 【Codeforces 738A】Interview with Oleg

    http://codeforces.com/contest/738/problem/A Polycarp has interviewed Oleg and has written the interv ...

  6. CodeForces - 662A Gambling Nim

    http://codeforces.com/problemset/problem/662/A 题目大意: 给定n(n <= 500000)张卡片,每张卡片的两个面都写有数字,每个面都有0.5的概 ...

  7. CodeForces - 274B Zero Tree

    http://codeforces.com/problemset/problem/274/B 题目大意: 给定你一颗树,每个点上有权值. 现在你每次取出这颗树的一颗子树(即点集和边集均是原图的子集的连 ...

  8. CodeForces - 261B Maxim and Restaurant

    http://codeforces.com/problemset/problem/261/B 题目大意:给定n个数a1-an(n<=50,ai<=50),随机打乱后,记Si=a1+a2+a ...

  9. CodeForces - 696B Puzzles

    http://codeforces.com/problemset/problem/696/B 题目大意: 这是一颗有n个点的树,你从根开始游走,每当你第一次到达一个点时,把这个点的权记为(你已经到过不 ...

随机推荐

  1. IbatchBolt和BaseTransactionalBolt区别

    void prepare(java.util.Map conf, TopologyContext context, BatchOutputCollector collector, T id) T id ...

  2. 洛谷P2073 送花 [2017年6月计划 线段树01]

    P2073 送花 题目背景 小明准备给小红送一束花,以表达他对小红的爱意.他在花店看中了一些花,准备用它们包成花束. 题目描述 这些花都很漂亮,每朵花有一个美丽值W,价格为C. 小明一开始有一个空的花 ...

  3. SASS在HTML5移动应用开发中的应用方法

    一.什么是SASS SASS是一种CSS的开发工具,提供了许多便利的写法,大大节省了设计者的时间,使得CSS的开发,变得简单和可维护. 本文总结了SASS的主要用法.二.安装和使用 2.1 安装 SA ...

  4. 将自己的代码托管到github - 秦时明月 - CSDN博客

    步骤: 1.建立自己的github 2.安装github客户端,并配置身份 3.建立github项目 4.将github项目库下载到本地 5.提交本地代码到github 详细操作: 1.github网 ...

  5. ant详细介绍

      Ant的概念 可能有些读者并不连接什么是Ant以及入可使用它,但只要使用通过Linux系统得读者,应该知道make这个命令.当编译Linux内核及一些软件的源程序时,经常要用这个命令.Make命令 ...

  6. c++新特性实验(1)预处理

    1.参考资料 1.1 C++ C++17 标准文档(正式)  :    https://www.iso.org/standard/68564.html C++ 标准文档(草案)      :   ht ...

  7. HR招聘_(七)_招聘方法论(面试环节·动机判断)

    候选人选择一般会看硬性技能,软性技能,动机意愿三个方面的匹配程度,硬性技能主要指纵向的业务能力,部门面试官也会着重看这方面,软性技能包括沟通,情商,气质等.动机意愿非常重要,再优秀的如果没有意愿,动机 ...

  8. 对于MD5加密处理方式

    来源:http://blog.51cto.com/xqtesting/1924977 但有时候我们请求的参数可能需要加密,比如登录接口中的密码可能需要经过md5加密这时候怎么处理呢? 这种方法比较简单 ...

  9. 【JZOJ3215】【SDOI2013】费用流

    ╰( ̄▽ ̄)╭ 对于一张给定的 运输网络 ,Alice 先确定一个最大流 ,如果有多种解, Alice 可以任选一种: 之后 Bob在每条边上分配单位花费 (单位花费必须是非负实数), 要求所有边的单 ...

  10. linux小介绍

    常用命令