[Codeforces702F]T-Shirts——非旋转treap+贪心
题目链接:
题目大意:有$n$种T恤,每种有一个价格$c_{i}$和品质$q_{i}$且每种数量无限。现在有$m$个人,第$i$个人有$v_{i}$元,每人每次会买他能买得起的品质最高的一件T恤(当两件T恤品质相同时优先买价格低的),每人只能买一件每种T恤。求最后每个人买的T恤件数。
暴力的方法是将T恤品质从大到小排序,对于每个人从第一种T恤(排序后的第一种)开始模拟每件T恤,能买就买,不能买就跳过。
发现暴力的方法是对于每个人决策每件T恤,我们可以对于每件T恤来决策哪些人能买,用非旋转$treap$来维护每个人还剩的钱数。
那么每次就是将权值大于$q_{i}$的人的权值都减少$q_{i}$并把答案都增加$1$。
对于区间修改我们直接打标记即可,但问题是无法将被修改的部分和没被修改的部分合并。
因为非旋转$treap$的合并要求一棵树的最大权值小于另一棵树的最小权值,而被修改部分在权值减小之后会有一部分的权值比未被修改部分最大权值小。
那么我们就把这部分暴力插入到未被修改的那棵树中,剩下被修改的那部分直接合并。
假设被暴力插入的权值为$x$,那么$x-q_{i}<q_{i},x>=q_{i}$,也就是说$2q_{i}>x,q_{i}>\frac{x}{2}$,即每次暴力插入的数权值减半,所以每个数最多暴力插入$log_{v_{i}}$次。
总时间复杂度是$O((n+\sum log_{v_{i}})log_{m})$。
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<cstdio>
#include<bitset>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
int ls[200010];
int rs[200010];
int val[200010];
int num[200010];
int r[200010];
int sum[200010];
int tag[200010];
int res[200010];
int root;
int n,m,x;
int cnt;
int a,b,c,d;
int L,R;
struct lty
{
int c,v;
}q[200010];
queue<int>Q;
inline int build(int v)
{
int rt=++cnt;
r[rt]=rand();
val[rt]=v;
return rt;
}
inline void add(int rt,int x,int y)
{
tag[rt]+=x;
val[rt]+=x;
sum[rt]+=y;
res[rt]+=y;
}
inline void pushdown(int rt)
{
if(tag[rt]&&sum[rt])
{
add(ls[rt],tag[rt],sum[rt]);
add(rs[rt],tag[rt],sum[rt]);
tag[rt]=sum[rt]=0;
}
}
inline int merge(int x,int y)
{
if(!x||!y)
{
return x+y;
}
pushdown(x);
pushdown(y);
if(r[x]<r[y])
{
rs[x]=merge(rs[x],y);
return x;
}
else
{
ls[y]=merge(x,ls[y]);
return y;
}
}
inline void split(int rt,int &x,int &y,int k)
{
if(!rt)
{
x=y=0;
return ;
}
pushdown(rt);
if(val[rt]>=k)
{
y=rt;
split(ls[rt],x,ls[y],k);
}
else
{
x=rt;
split(rs[rt],rs[x],y,k);
}
}
inline bool cmp(lty a,lty b)
{
return a.v==b.v?a.c<b.c:a.v>b.v;
}
inline void dfs(int rt)
{
pushdown(rt);
if(ls[rt])
{
dfs(ls[rt]);
}
if(rs[rt])
{
dfs(rs[rt]);
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d%d",&q[i].c,&q[i].v);
}
sort(q+1,q+1+n,cmp);
scanf("%d",&m);
for(int i=1;i<=m;i++)
{
scanf("%d",&x);
split(root,a,b,x);
root=merge(merge(a,build(x)),b);
}
for(int i=1;i<=n;i++)
{
split(root,a,b,q[i].c);
split(b,b,c,2*q[i].c);
add(b,-q[i].c,1);
add(c,-q[i].c,1);
Q.push(b);
while(!Q.empty())
{
int now=Q.front();
Q.pop();
pushdown(now);
if(ls[now])
{
Q.push(ls[now]);
}
if(rs[now])
{
Q.push(rs[now]);
}
ls[now]=rs[now]=0;
split(a,a,d,val[now]);
a=merge(merge(a,now),d);
}
root=merge(a,c);
}
dfs(root);
for(int i=1;i<=m;i++)
{
printf("%d ",res[i]);
}
}
[Codeforces702F]T-Shirts——非旋转treap+贪心的更多相关文章
- [bzoj3173]最长上升子序列_非旋转Treap
最长上升子序列 bzoj-3173 题目大意:有1-n,n个数,第i次操作是将i加入到原有序列中制定的位置,后查询当前序列中最长上升子序列长度. 注释:1<=n<=10,000,开始序列为 ...
- 关于非旋转treap的学习
非旋转treap的操作基于split和merge操作,其余操作和普通平衡树一样,复杂度保证方式与旋转treap差不多,都是基于一个随机的参数,这样构出的树树高为\(logn\) split 作用:将原 ...
- BZOJ5063旅游——非旋转treap
题目描述 小奇成功打开了大科学家的电脑. 大科学家打算前往n处景点旅游,他用一个序列来维护它们之间的顺序.初 始时,序列为1,2,...,n. 接着,大科学家进行m次操作来打乱顺序.每次操作有6步: ...
- BZOJ3223文艺平衡树——非旋转treap
此为平衡树系列第二道:文艺平衡树您需要写一种数据结构,来维护一个有序数列,其中需要提供以下操作: 翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1 ...
- BZOJ3224普通平衡树——非旋转treap
题目: 此为平衡树系列第一道:普通平衡树您需要写一种数据结构,来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个)3. 查询x数的排名(若有多个相同的数, ...
- [NOIP]2017列队——旋转treap/非旋转treap
Sylvia 是一个热爱学习的女孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia所在的方阵中有n × m名学生,方阵的行数为 n,列数为m. 为了便 ...
- BZOJ3729Gty的游戏——阶梯博弈+巴什博弈+非旋转treap(平衡树动态维护dfs序)
题目描述 某一天gty在与他的妹子玩游戏.妹子提出一个游戏,给定一棵有根树,每个节点有一些石子,每次可以将不多于L的石子移动到父节点,询问将某个节点的子树中的石子移动到这个节点先手是否有必胜策略.gt ...
- BZOJ1552[Cerc2007]robotic sort&BZOJ3506[Cqoi2014]排序机械臂——非旋转treap
题目描述 输入 输入共两行,第一行为一个整数N,N表示物品的个数,1<=N<=100000. 第二行为N个用空格隔开的正整数,表示N个物品最初排列的编号. 输出 输出共一行,N个用空格隔开 ...
- BZOJ1251序列终结者——非旋转treap
题目描述 网上有许多题,就是给定一个序列,要你支持几种操作:A.B.C.D.一看另一道题,又是一个序列 要支持几种操作:D.C.B.A.尤其是我们这里的某人,出模拟试题,居然还出了一道这样的,真是没技 ...
随机推荐
- BIM特点及格式文件说明
BIM行业是建筑与IT结合而形成的一个新兴行业,既然能说是行业,说明它包含的内容非常丰富,懂一点和完全懂是两码事,就好像一滴水和一片大海的范围一样.现在国内有很多高校开设了BIM专业,并对口招收了学生 ...
- Android BottomNavigationBar导航栏
基本属性 setActiveColor //选中item的字体颜色 setInActiveColor //未选中Item中的颜色 setBarBackgroundColor//背景颜色 setMode ...
- <4>Python切片功能剖析
引用文章:https://mp.weixin.qq.com/s/NZ371nKs_WXdYPCPiryocw 切片基础法则: (1)公式,禁止0. (2)i, n同号:从序列的第i位索引起,向右取n- ...
- matlab练习程序(神经网络识别mnist手写数据集)
记得上次练习了神经网络分类,不过当时应该有些地方写的还是不对. 这次用神经网络识别mnist手写数据集,主要参考了深度学习工具包的一些代码. mnist数据集训练数据一共有28*28*60000个像素 ...
- Got a packet bigger than‘max_allowed_packet’bytes错误的解决方法
通常项目上线前都有一些初始化数据需要导入,在今天博客系统发布前我使用sqlyog工具远程登录服务器的Mysql数据库,执行sql脚本对初始数据进行导入的时候报错: Got a packet bigge ...
- Mina的IoBuffer改造成Netty的ByteBuff
背景:部标GPS通讯底层全部改造成基于Netty服务器实现的,现将Mina的依赖移除,修改过程中有用到缓冲区的读写.现做了如下修改: 原有基于Mina的IoBuffer对字节读写封装代码如下: pac ...
- python3 Counter类(计数器)
Counter(计数器):用于追踪值的出现次数 Counter类继承dict类,所以它能使用dict类里面的方法 创建一个Counter类 import collections obj = colle ...
- 转:[kipmi0]进程导致系统负载高
最近一个用户这边服务器出现服务器负载很高的情况,原本正常是0.3~0.5左右 不正常的时候会达到3,重启机器就正常,开始以为是程序问题,后来在观察的时候把程序给杀掉了 然后重启,结果负载还是很高,于 ...
- Windows server 2012 R2 部署WSUS补丁服务
一.WSUS 安装要求 1.硬件要求: 对于多达 13000 个客户端的服务器,建议使用以下硬件:* 4 Core E5-2609 2.1GHz 的处理器* 8 GB 的 RAM 2.软件要求: 要使 ...
- 英语口语练习系列-C14-常用片语
句子 1. Some ads are extremely persuasive and we find we buy products we don't really need. 有一些广告非常有说服 ...