[cf1515I]Phoenix and Diamonds
将$n$类物品按照价值为第一关键字(从大到小)、质量为第二关键字(从小到大)排序,此时贪心策略即依次贪心选(排序后)第$i$类的物品(其中$i$从1到$n$)
为了方便,排序后第$i$类物品质量、价值和个数仍用$w_{i},v_{i}$和$a_{i}$描述(即默认初始排序)
$\forall 0\le k\le 30$,维护一棵线段树,其中区间$[l,r]$维护:
1.$\sum_{l\le i\le r,w_{i}<2^{k}}a_{i}w_{i}$和$\sum_{l\le i\le r,w_{i}<2^{k}}a_{i}v_{i}$(特别的,若$w_{i}\ge 2^{k}$则$a_{i}$强制为0)
2.$\min_{l\le j\le r,2^{k}\le w_{j}<w^{k+1},a_{j}\ge 1}(\sum_{l\le i<j,w_{i}<2^{k}}a_{i}w_{i}+w_{j})$(特别的,若不存在$j$则强制为$\infty$)
修改操作会影响$o(\log n)$棵线段树,单次修改复杂度即$o(\log^{2}n)$
设已经贪心到第$l$类物品(第$l$类还未贪心),箱子剩余的容纳质量为$c$,取最大的$0\le k\le 30$满足$c\ge 2^{k}$
考虑找到最小的$r$,满足$\min_{l\le j\le r,2^{k}\le w_{j}<w^{k+1},a_{j}\ge 1}(\sum_{l\le i<j,w_{i}<2^{k}}a_{i}w_{i}+w_{j})\le c$,通过在$k$对应的线段树上二分即可做到$o(\log n)$的复杂度
若存在这样的$r$,此时即将$c$减去$\sum_{l\le i<r,w_{i}<2^{k}}a_{i}w_{i}+w_{r}$,答案增加$\sum_{l\le i<r,w_{i}<2^{k}}a_{i}v_{i}+v_{r}$
若不存在这样的$r$,再找到最小的$r$,满足$\sum_{l\le i\le r,w_{i}<2^{k}}a_{i}w_{i}>c$,同样在线段树上二分实现
此时即将$c$减去$\sum_{l\le i<r,w_{i}<2^{k}}a_{i}w_{i}$,答案增加$\sum_{l\le i<r,w_{i}<2^{k}}a_{i}v_{i}$,再手动贪心第$r$类物品(特别的,若$r>n$则跳过这一步)
最终,再把$l$变为$r+1$即可
关于正确性,分析如下——
对于第一种情况,即选择了$[l,r)$中所有$w_{i}<2^{k}$的物品,也即求证若$r'$满足$l\le r'<r$且$w_{r'}\ge 2^{k}$,$w_{r'}$必然不会被选择,对$w_{r'}$的情况分类讨论:
1.$w_{r'}<2^{k+1}$,此时如果会被选择,显然将$r$变为$r'$更优
2.$w_{r'}\ge 2^{k+1}$,若$c=30$显然不存在此类物品,否则必然有$c<2^{k+1}$,也不能被选择
而对于$w_{r}$,上述式子的最小值必然在$j=r$时取到(否则令$r$为取到最小值的$j$更优),即$w_{r}\ge 2^{k}$,因此$w_{r}$至多选择一个,且可以被选择,即选择一个即可
对于第二种情况,由于不存在$r$,也即一定不能选择$w_{i}\ge 2^{k}$的物品,因此仅考虑$w_{i}<2^{k}$的物品即可
关于最后的手动贪心,若$w_{r}\ge 2^{k}$显然将$r$变为$r+1$更优,因此必然有$w_{r}<2^{k}$,且一定不能全部选择(同样将$r$变为$r+1$更优)
关于时间复杂度,分析如下——
事实上,不论哪一种情况,最终都会有$c<2^{k}$或$l>n$
第一种情况,由于选择了$w_{r}\ge 2^{k}$的物品,显然$c<2^{k}$
第二种情况,由于最终手动贪心第$r$类物品,根据前面的分析$w_{r}<2^{k}$且不能全部选择,那么最终若$c\ge 2^{k}$则还可以再选一个$w_{r}$的物品(特别的,若$r>n$即$l>n$)
由此,上述过程至多执行$o(\log n)$次,单次询问复杂度即$o(\log^{2}n)$
综上,总时间复杂度为$o(n\log^{2}n)$,可以通过

1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 200005
4 #define ll long long
5 #define L (k<<1)
6 #define R (L+1)
7 #define mid (l+r>>1)
8 struct Thing{
9 int a,w,v,id;
10 bool operator < (const Thing &k)const{
11 return ((v>k.v)||(v==k.v)&&(w<k.w));
12 }
13 }a[N];
14 struct Data{
15 ll w,v,mn;
16 }o,f[31][N<<2];
17 int n,q,p,x,y,id[N];
18 ll z;
19 void get(int k,int x){
20 for(int i=0;i<=30;i++){
21 f[i][k]=o;
22 if (a[x].w<(1<<i)){
23 f[i][k].w=1LL*a[x].a*a[x].w;
24 f[i][k].v=1LL*a[x].a*a[x].v;
25 }
26 else{
27 if ((i<30)&&(a[x].w<(1<<i+1))&&(a[x].a>=1))f[i][k].mn=a[x].w;
28 }
29 }
30 }
31 Data merge(Data x,Data y){
32 return Data{x.w+y.w,x.v+y.v,min(x.mn,y.mn+x.w)};
33 }
34 void up(int k){
35 for(int i=0;i<=30;i++)f[i][k]=merge(f[i][L],f[i][R]);
36 }
37 void build(int k,int l,int r){
38 if (l==r){
39 get(k,l);
40 return;
41 }
42 build(L,l,mid);
43 build(R,mid+1,r);
44 up(k);
45 }
46 void update(int k,int l,int r,int x){
47 if (l==r){
48 get(k,x);
49 return;
50 }
51 if (x<=mid)update(L,l,mid,x);
52 else update(R,mid+1,r,x);
53 up(k);
54 }
55 Data query(int p,int k,int l,int r,int x,int y){
56 if ((l>y)||(x>r))return o;
57 if ((x<=l)&&(r<=y))return f[p][k];
58 return merge(query(p,L,l,mid,x,y),query(p,R,mid+1,r,x,y));
59 }
60 int find1(int p,int k,int l,int r,int x,ll &y){//找到大于等于x的位置中第一个mn<=y的位置
61 if (r<x)return n+1;
62 if ((l>=x)&&(f[p][k].mn>y)){
63 y-=f[p][k].w;
64 return n+1;
65 }
66 if (l==r)return l;
67 int ans=find1(p,L,l,mid,x,y);
68 if (ans<=n)return ans;
69 return find1(p,R,mid+1,r,x,y);
70 }
71 int find2(int p,int k,int l,int r,int x,ll &y){//找到大于等于x的位置中第一个w>y的位置
72 if (r<x)return n+1;
73 if ((l>=x)&&(f[p][k].w<=y)){
74 y-=f[p][k].w;
75 return n+1;
76 }
77 if (l==r)return l;
78 int ans=find2(p,L,l,mid,x,y);
79 if (ans<=n)return ans;
80 return find2(p,R,mid+1,r,x,y);
81 }
82 ll query(ll c){
83 int pos=1;
84 ll cc,ans=0;
85 while ((pos<=n)&&(c)){
86 int k=0,nex;
87 for(int i=0;i<=30;i++)
88 if ((1<<i)<=c)k=i;
89 nex=find1(k,1,1,n,pos,cc=c);
90 if (nex<=n){
91 Data o=query(k,1,1,n,pos,nex-1);
92 c-=o.w+a[nex].w,ans+=o.v+a[nex].v;
93 }
94 else{
95 nex=find2(k,1,1,n,pos,cc=c);
96 Data o=query(k,1,1,n,pos,nex-1);
97 c-=o.w,ans+=o.v;
98 if (nex<=n){
99 ll s=c/a[nex].w;
100 c-=s*a[nex].w,ans+=s*a[nex].v;
101 }
102 }
103 pos=nex+1;
104 }
105 return ans;
106 }
107 int main(){
108 o.mn=2e18;
109 scanf("%d%d",&n,&q);
110 for(int i=1;i<=n;i++){
111 scanf("%d%d%d",&a[i].a,&a[i].w,&a[i].v);
112 a[i].id=i;
113 }
114 sort(a+1,a+n+1);
115 for(int i=1;i<=n;i++)id[a[i].id]=i;
116 build(1,1,n);
117 for(int i=1;i<=q;i++){
118 scanf("%d",&p);
119 if (p==1){
120 scanf("%d%d",&x,&y);
121 y=id[y];
122 a[y].a+=x;
123 update(1,1,n,y);
124 }
125 if (p==2){
126 scanf("%d%d",&x,&y);
127 y=id[y];
128 a[y].a-=x;
129 update(1,1,n,y);
130 }
131 if (p==3){
132 scanf("%lld",&z);
133 printf("%lld\n",query(z));
134 }
135 }
136 }
[cf1515I]Phoenix and Diamonds的更多相关文章
- Phoenix综述(史上最全Phoenix中文文档)
个人主页:http://www.linbingdong.com 简书地址:http://www.jianshu.com/users/6cb45a00b49c/latest_articles 网上关于P ...
- 在DBeaver中phoenix查询报错:org.apache.phoenix.exception.PhoenixIOException: The system cannot find the path specified
环境:Phoenix:4.4,win7系统 问题:Phoenix在查询hbase时,报"系统找不到指定路径". 解决: 请参见 https://distcp.quora.com/C ...
- HBase+Phoenix整合入门--集群搭建
环境:CentOS 6.6 64位 hbase 1.1.15 phoenix-4.7.0-HBase-1.1 一.前置环境: 已经安装配置好Hadoop 2.6和jdk 1.7 二.安装hba ...
- SQL Server恢复软件 Stellar Phoenix sql recovery
SQL Server恢复软件 Stellar Phoenix sql recovery http://www.stellarinfo.com/ http://www.stellarinfo.com/ ...
- Hbase+ Phoenix搭建教程
Hbase+ Phoenix搭建教程 一.Hbase简介 HBase是基于列存储.构建在HDFS上的分布式存储系统,其主要功能是存储海量结构化数据. HBase构建在HDFS之上,因此HBase也是通 ...
- CDH5.4.5运行Phoenix导入CSV文件
1.安装phoenix 在界面上设置Phoenix的parcel包: http://52.11.56.155:7180/cmf/settings?groupKey=config.scm.parcel. ...
- Phoenix -修复表索引
索引的修复可以通过2种方式,(关于pehoenix的索引的生命周期可以参考 https://community.hortonworks.com/articles/58818/phoenix-inde ...
- phoenix将hdfs数据导入hbase
http://phoenix.apache.org/bulk_dataload.html
- phoenix 开发API系列 目录
phoenix 开发API系列(一)创建简单的http api phoenix 开发API系列(二)phoenix 各类 api 实现方式 phoenix 开发API系列(三)phoenix api ...
随机推荐
- 记一次Kafka服务器宕机的真实经历!!
大家好,我是冰河~~ 估计节前前祭拜服务器不灵了,年后服务器总是或多或少的出现点问题.不知是人的问题,还是风水问题.昨天下班时,跟运维小伙伴交代了好几遍:如果使用Docker安装Kafka集群的话,也 ...
- 华为Awareness kit,您旅途路上的超智能管家
前言 前段时间看了一部纪录片<中国游客在巴黎>,讲述了外国人眼中"中国式旅游":热衷景点打卡,沉迷拍照留念,无暇仔细欣赏:留足时间,买买买,不能枉此行.网友总结中国式旅 ...
- C#开发BIMFACE系列49 Web网页中加载模型与图纸的技术方案
BIMFACE二次开发系列目录 [已更新最新开发文章,点击查看详细] 在BIMFACE二次系列博客中详细介绍了服务器端API的调用方式,如下列表 C#开发BIMFACE系列1 BIMFAC ...
- C#开发BIMFACE系列48 Nginx部署并加载离线数据包
BIMFACE二次开发系列目录 [已更新最新开发文章,点击查看详细] 在前一篇博客<C#开发BIMFACE系列47 IIS部署并加载离线数据包>中详细介绍了IIS部署并访问的完整步 ...
- 海信A6/A6L A7Pro/CC A5PRO/A5PRO CC 安装gms google service指南
用过海信双面屏或者eink手机的朋友都知道,海信手机就是死活安装不了谷歌全家桶,因为海信的领导说跟谷歌有协议不能安装谷歌框架(还说后期google审核坚决不给安装,人家其他ov mui都可以安装).不 ...
- 利用python爬取全国水雨情信息
分析 我们没有找到接口,所以打算利用selenium来爬取. 代码 import datetime import pandas as pd from bs4 import BeautifulSoup ...
- 微信小程序的支付流程
一.前言 微信小程序为电商类小程序,提供了非常完善.优秀.安全的支付功能 在小程序内可调用微信的API完成支付功能,方便.快捷 场景如下图所示: 用户通过分享或扫描二维码进入商户小程序,用户选择购买, ...
- Beta阶段第六次会议
第六次会议 时间:2020.5.22 完成工作 姓名 任务 难度 完成度 xyq 1.编写技术博客 中 90% ltx 1.编写小程序2.添加全局变量之后页面无法加载的bug 中 90% lm(迟到) ...
- Prometheus基于Eureka的服务发现
Prometheus基于Eureka的服务发现 一.背景 二.实现步骤 1.eureka 客户端注册到prometheus中 2.prometheus中的写法 3.实现效果 三.完整代码 四.参考链接 ...
- 简明教程 | Docker篇 · 其二:Dockerfile的编写
Dockerfile是什么 一个包含用于组合 image 的命令的文本文件,docker 通过 dockerfile 和构建环境的上下文来构建 image . 编写Dockerfile FROM 首先 ...