题目大意:

有n件T-shirt,每件T-shirt有一个val值和price值
还有m个顾客,每个顾客有一个最大金额Bi
每个顾客的购买策略是相同的:
他会买他的资金范围内val值最大的一件,
而且每种T-shirt都只能买1次
直到所有的T-shirt他都买不起或者他都买过了,那么

n,m<=100000

分析

其实这道题的难点主要在第一步,就是如何建树,
很容易就会想到用T-shirt来建树,但是这样的话其实是很难做的(反正我没想出来)
因为你既要考虑不能重复买,又不能很容易地做到满足时间复杂度

换一种思路,用人的钱来建平衡树
这样一来就很容易了,因为每个人买衣服的策略是一样的
所以如果按照T-shirt的优先级排序,再依次考虑,就会显得很简单

假设当前考虑到第i件T-shirt,其price值为PiP_i
那么很容易想到,在平衡树中所有权值大于PiP_i的点,
都要减去PiP_i,这样一来,我们就要考虑平衡树区间加减就可以了

那么如何用神奇的范浩强Treap来处理平衡树的区间加减呢?
画个图分析一下(肥肠抱歉,下面两个图PiP_i写成了ViV_i):


很容易发现,平衡树中减去PiP_i后会有值域重复部分,这样的部分不可能通过Merge操作来完成
那么要怎么做呢????

其实很简单,暴力地将其中一部分中每个节点依次插入平衡树即可。
你是不是本能地认为会超时?
然而,经过很简单的证明,可以得到是不会超时的。

BiB_i为第i个人的金额,PiP_i为他需要支付的钱
那么如果这个人需要暴力插入,那么必须满足:

Pi≤Bi≤2Pi

P_i≤B_i≤2P_i
所以

Bi2≤Pi

\frac{B_i} 2≤P_i
要知道的是, BiB_i每次操作后都需要减去 PiP_i,简而言之,如果要暴力操作,那么 BiB_i至少要减去它的一半,所以最多会被暴力 log(Bi)log(B_i)次,就不会超时了

我的范浩强Treap的模板比较丑,下面这个代码卡时限卡得非常紧,因此加了一堆优化,但主体思路并没变。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#define SF scanf
#define PF printf
#define MAXN 200010
using namespace std;
struct node{int ch[2];int key,fix,sum,add,cnt,cnts;int id;node() {}node(int key1,int id1):key(key1),fix(rand()),sum(1),add(0),cnt(0),cnts(0),id(id1) {}
}Tree[MAXN];
int root,ncnt;
void update(int x){Tree[x].sum=Tree[Tree[x].ch[0]].sum+Tree[Tree[x].ch[1]].sum+1;Tree[x].cnt+=Tree[x].cnts;Tree[x].key+=Tree[x].add;if(Tree[x].ch[0]){Tree[Tree[x].ch[0]].add+=Tree[x].add;Tree[Tree[x].ch[0]].cnts+=Tree[x].cnts;}if(Tree[x].ch[1]){Tree[Tree[x].ch[1]].add+=Tree[x].add;Tree[Tree[x].ch[1]].cnts+=Tree[x].cnts;}Tree[x].cnts=0;Tree[x].add=0;
}
int Merge(int x,int y){if(x==0) return y;if(y==0) return x;update(x);update(y);if(Tree[x].fix<Tree[y].fix){Tree[x].ch[1]=Merge(Tree[x].ch[1],y);update(x);return x;}else{Tree[y].ch[0]=Merge(x,Tree[y].ch[0]);update(y);return y;}
}
pair<int,int> Split(int x,int k){if(x==0) return make_pair(0,0);pair<int,int> y;update(x);if(Tree[x].key<=k){y=Split(Tree[x].ch[1],k);Tree[x].ch[1]=y.first;update(x);y.first=x;}else{y=Split(Tree[x].ch[0],k);Tree[x].ch[0]=y.second;update(x);y.second=x;}return y;
}
void Insert(int val,int id){Tree[++ncnt]=node(val,id);Tree[ncnt].ch[0]=0;Tree[ncnt].ch[1]=0;root=Merge(root,ncnt);
}
void dfs1(int x){if(x==0)return ;update(x);dfs1(Tree[x].ch[0]);dfs1(Tree[x].ch[1]);Tree[x].ch[0]=0;Tree[x].ch[1]=0;pair<int,int> y=Split(root,Tree[x].key);root=Merge(Merge(y.first,x),y.second);
}
void solve(int val){pair<int,int> x=Split(root,val-1);Tree[x.second].add-=val;Tree[x.second].cnts++;//PF("[%d %d]",x.first,x.second);pair<int,int> y=Split(x.second,val);if(Tree[x.first].sum<Tree[y.first].sum){root=Merge(y.first,y.second);dfs1(x.first);}else{root=Merge(x.first,y.second);dfs1(y.first);}
}
int ans[MAXN];
void dfs(int x,int sum){if(x==0)return ;ans[Tree[x].id]=sum+Tree[x].cnt+Tree[x].cnts;dfs(Tree[x].ch[0],sum+Tree[x].cnts);dfs(Tree[x].ch[1],sum+Tree[x].cnts);
}
int n,m,x,id;
pair<int,int> p[MAXN];
void Read(int &x){char c;bool flag=0;while(c=getchar(),c!=EOF&&(c<'0'||c>'9')&&c!='-')if(c=='-'){c=getchar();flag=1;}x=c-'0';while(c=getchar(),c!=EOF&&c>='0'&&c<='9')x=x*10+c-'0';
}
pair<int,int> cost[MAXN];
int main(){srand(32);SF("%d",&n);for(int i=1;i<=n;i++){Read(p[i].second);Read(p[i].first);p[i].first*=-1;}sort(p+1,p+1+n);SF("%d",&m);for(int i=1;i<=m;i++){SF("%d",&cost[i].first);cost[i].second=i;}sort(cost+1,cost+1+m);for(int i=1;i<=m;i++)Insert(cost[i].first,cost[i].second);for(int i=1;i<=n;i++){/*for(int j=1;j<=m;j++)PF("[%d %d %d %d %d]lson:%d  rson:%d\n",j,Tree[j].key,Tree[j].add,Tree[j].cnt,Tree[j].cnts,Tree[j].ch[0],Tree[j].ch[1]);PF("------------------------------------\n");*/solve(p[i].second);}dfs(root,0);for(int i=1;i<=m;i++)PF("%d ",ans[i]);
}

【数据结构】【范浩强Treap】CF702F T-shirt相关推荐

  1. 谭浩强《C++程序设计》学习

    谭浩强<C++程序设计>学习 zdh1995 2017-10-12 15:54:56  5613  收藏 251 文章标签: c++ 版权 C++ 不要把面向对象和基于过程对立起来,面向对 ...

  2. c++程序设计梳理(谭浩强)3-4章

    为什么80%的码农都做不了架构师?>>>    同学拿了58的offer,22万一年,内心多少有点不是滋味.自己享受着这么丁点的中兴薪酬,明显是学业不精的那一类.事实确实如此,可当现 ...

  3. 谭浩强C程序设计第四版答案

    只给出一些需要编程的答案,用的是谭浩强老师的书: 本文持续更新中- C程序设计课本中的一些笔记见:C程序设计笔记 我的目录 只给出一些需要编程的答案,用的是谭浩强老师的书: 本文持续更新中... C程 ...

  4. 谭浩强c语言入门_计算机学生为什么学不会C语言?看到这4点原因,学生表示太真实...

    C语言是理工科(特别是计算机专业)的必修课之一,是计算机应用的基本技能,本来是一门简单的课程,在程序员眼里算是"体力活",不需要太多智力.但是,看似这样一门简单课程,计算机专业学生 ...

  5. c语言谭浩强ppt课件,编程_C语言学习课件_谭浩强_PPT~1216F.ppt

    编程_C语言学习课件_谭浩强_PPT~1216F.ppt ,第一章,C语言概述本章要点,C语言的特点 C程序的结构 在计算机上运行C程序的方法主要内容,1.1 语言出现的历史背景 1.2 程序的特点 ...

  6. DSt:数据结构的最强学习路线之数据结构知识讲解与刷题平台、刷题集合、问题为导向的十大类刷题算法(数组和字符串、栈和队列、二叉树、堆实现、图、哈希表、排序和搜索、动态规划/回溯法/递归/贪心/分治)总

    DSt:数据结构的最强学习路线之数据结构知识讲解与刷题平台.刷题集合.问题为导向的十大类刷题算法(数组和字符串.栈和队列.二叉树.堆实现.图.哈希表.排序和搜索.动态规划/回溯法/递归/贪心/分治)总 ...

  7. C程序设计(谭浩强第五版)总结

    C程序设计(谭浩强第五版)总结 本篇文章主要是总结谭浩强第五版C语言书上的重点和易漏点的知识点,其目的主要是给高校期末考试的同学们点参考.本文所参考的书籍是谭浩强的<C程序设计(第五版)> ...

  8. 谭浩强C语言程序设计(1-3章代码学习)

    谭浩强C语言程序设计 参考书 C语言学习笔记记录,学习为主,新手小白入门 我所用的C语言在线编译器:lightly在线编译工具 可新建工程 谭浩强C语言程序设计书籍所包含的代码示例加注释说明如下: / ...

  9. 谭浩强版c语言笔记(1)

    第1章 程序设计和c语言 1)机器指令:计算机能够识别和接受的二进制代码 2)机器语言:机器指令的集合 3)计算机程序:控制计算机操作的指令 第2章 一个程序主要包含两方面信息:对数据的描述(数据结构 ...

  10. 为什么很多人吐槽谭浩强的C语言程序设计,端碗吃饭放碗骂娘?

    这个观点在网络上已经论战了很长时间,出现这种情况还是历史遗留问题,谭浩强出的C语言教材几乎是国内的第一版,由于中英翻译问题或者对编程文化理解的差异性导致出来的书多多少少存在一些纰漏.不能只是记住其缺点 ...

最新文章

  1. cocos2d-x注意事项(十)Lua发展飞机战争-4-创建主角
  2. Linux软连接和硬链接
  3. 【设计模式】-写在前面
  4. 51CTO第2本书样章曝光:DHCP服务器规划与应用案例
  5. Spring基于配置方式实现自定义条件装配
  6. 收集下关系数据库处理亿万级别的数据
  7. android studio 中 gradle 配置与说明
  8. 哈尔滨大学计算机和金融,山东153所大学最新排名,46所公办本科,看看有你喜欢的吗...
  9. 手写 Promise.all
  10. Visio 2003软件安装教程
  11. 联想计算机不能使用ghost,联想电脑不能GHOST的解决方法
  12. 层次聚类python实现
  13. 计算机二级相关快捷键,计算机二级考试Word+Excel必备快捷键!
  14. pandas将df赋值到另一个df_Python/Pandas:如果匹配的話,將一個df的值添加到另一個df的行的末尾...
  15. 大陆移动手机卡开通国际漫游(港澳台)
  16. 阅读笔记-原生家庭·如何修补自己的性格缺陷
  17. 二级c语言编译完程序如何运行,计算机二级C语言辅导:C++环境下编译和运行c语言...
  18. 微信支付失败提示签名错误,请检查后重试
  19. Oracle中一个汉字占几个字节
  20. OLED模块以及OLED屏幕上显示

热门文章

  1. 三角形花园和向左走(三角形性质和点集排序)
  2. Linux哲学家进餐杀死进程,经典进程的同步问题之——哲学家进餐
  3. 2016 server win 假死_Win7运行程序无缘无故发生假死现象五种解决方法
  4. 云计算与大数据之间的关系
  5. 【转载】如何成为优秀的网络安全工程师
  6. Windows10教育版升级至专业版的方法
  7. 2016年剩一个月规划已将2017年展望
  8. 台计算机的本地打印机 并且,您在计算机上安装一台本地打印机。您共享这台打印机。您需要确保只有名为Grou..._考试资料网...
  9. 易佰USB转串口驱动
  10. 3 Layer and 3 Tier