[Apio2012]dispatching 主席树做法
bzoj 2809: [Apio2012]dispatching
http://www.lydsy.com/JudgeOnline/problem.php?id=2809
Description
Input
Output
Sample Input
0 3 3
1 3 5
2 2 2
1 2 4
2 3 1
Sample Output
HINT
如果我们选择编号为 1的忍者作为管理者并且派遣第三个和第四个忍者,薪水总和为 4,没有超过总预算。
因为派遣了2 个忍者并且管理者的领导力为 3,用户的满意度为 6 ,是可以得到的用户满意度的最大值。
题目剖析:
ans=领导力*个数
领导力:枚举每个忍者
个数:当然是需要薪水少的先派遣啦
所以,节点的领导力为a,在以这个节点为根的子树中(包括这个节点),从小到大选尽可能多的节点s,满足节点的薪水和<=总预算,最大化a*s
这道题还可以用左偏树来做,但蒟蒻一枚只会主席树 ,所以这里只写主席树做法
推荐黄学长的博客,维护子树大根堆,用可并堆将时间复杂度降为nlongn http://hzwer.com/5682.html
数据结构:主席树
辅助:dfs序(开始没想到)
以忍者的dfs序为下标,薪水为区间建立主席树
首先说说dfs序
1、为什么需要dfs序?
因为派遣忍者的范围是以这个忍者为根的子树。
假设当前节点为i,遍历到时令 in[i]=a, 表示i是第a个被遍历。以i为节点的子树遍历完后,令out[i]=b,b为当前所有已遍历节点总数
那么这个节点可以派遣的范围是dfs序[a,b](包括a,b)之间的忍者
所dfs序的作用是锁定查找区间
2、如何构造dfs序?(自己也没想到)
令t表示当前已遍历节点总数,每遍历一个节点t++,设当前节点为i,遍历到i是in[i]=t,i退出时out[i]=t
在构造dfs序时,顺便记录下dfs序为i的忍者的薪水、领导力,然后按照dfs序在主席树中插入节点
最后是查找
枚举每个忍者,查找他的派遣范围最多能派遣多少个忍者
如果做过[CQOI2015]任务查询系统,会知道那道题在查询查到叶子节点时,对答案的贡献是sum[l]/count[l]*k
本题查询的是数量,到叶子节点时有没有坑呢?
有。叶子节点对答案有贡献的忍者数量应该是 min(薪水预算/派遣这个节点的忍者所需薪水,这个节点的忍者个数)
这里的节点是主席树中以薪水为区间建立的节点
还有就是要注意答案用long long
#include<cstdio> #include<algorithm> #define N 100001 using namespace std; int n,m,money[N],lead[N],front[N],next[N]; int hash[N],cnt_money; int in[N],out[N],t; int root[N],tot,lc[N*20],rc[N*20],cnt[N*20]; long long sum[N*20],ans,dispatch; struct node {int mon,lea; }e[N]; inline void add(int u,int v) {next[v]=front[u];front[u]=v; } inline int dfs(int r) {in[r]=++t;e[t].lea=lead[r];e[t].mon=hash[r];if(front[r])for(int i=front[r];i;i=next[i])dfs(i);out[r]=t; } void discrete() {sort(money+1,money+n+1); cnt_money=unique(money+1,money+n+1)-(money+1);for(int i=1;i<=n;i++) hash[i]=lower_bound(money+1,money+cnt_money+1,hash[i])-money; } inline void insert(int pre,int & now,int l,int r,int w) {sum[now=++tot]=sum[pre]+money[w];cnt[now]=cnt[pre]+1;if(l==r) return;int mid=l+r>>1;if(w<=mid){rc[now]=rc[pre];insert(lc[pre],lc[now],l,mid,w);}else{lc[now]=lc[pre];insert(rc[pre],rc[now],mid+1,r,w);} } inline int query(int x,int y,int l,int r,long long k) {if(l==r) return min(k/(long long)money[l],(long long)(cnt[y]-cnt[x]));int mid=l+r>>1;long long tmp=sum[lc[y]]-sum[lc[x]];if(k<=tmp) return query(lc[x],lc[y],l,mid,k);else return cnt[lc[y]]-cnt[lc[x]]+query(rc[x],rc[y],mid+1,r,k-tmp); } int main() {scanf("%d%lld",&n,&m);int b,c,l;for(int i=1;i<=n;i++){scanf("%d%d%d",&b,&money[i],&lead[i]);hash[i]=money[i];add(b,i);}discrete();dfs(front[0]);for(int i=1;i<=n;i++) insert(root[i-1],root[i],1,cnt_money,e[i].mon); for(int i=1;i<=n;i++){int l=in[i],r=out[i];//l:节点i的dfs序,r节点i可以派遣的最靠后的忍者的dfs序 dispatch=query(root[l-1],root[r],1,cnt_money,m);ans=max(ans,(long long)lead[i]*dispatch);}printf("%lld",ans); }
这道题做的时候
1、没有想到用dfs序锁定查找区间
2、ans=max(忍者的领导力*派遣忍者个数),没有想到可以枚举每个忍者,这样就解决了领导力的问题。对答案的分解能力欠缺
3、答案没用long long,开始做的时候还想着答案用long long,想先写出来过了样例后再改,结果忘了
4、查询时,如果当前区间为[x,y],要到节点的右孩子去查询,返回的答案应是区间左右端点左孩子的cnt差,而不是y的cnt。这里与任务查询系统混了,因为任务查询系统查询的区间是[0,y],0可以省略,所以可以直接用y的cnt、sum
转载于:https://www.cnblogs.com/TheRoadToTheGold/p/6368387.html
[Apio2012]dispatching 主席树做法相关推荐
- BZOJ3473:字符串(后缀数组,主席树,二分,ST表)
Description 给定n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中至少k个字符串的子串? Input 第一行两个整数n,k. 接下来n行每行一个字符串. Output 一 ...
- Governing sand(权值线段树/主席树)
链接:https://ac.nowcoder.com/acm/contest/887/C 来源:牛客网 时间限制:C/C++ 3秒,其他语言6秒 空间限制:C/C++ 65536K,其他语言13107 ...
- P4216 [SCOI2015]情报传递 LCA+树上主席树 离线操作
题意: 给你一棵n个点的树,初始每个位置没有点权 有m次操作 1 x:让一个点从当前时刻开始,每秒操作点权++ 2 x y c:查询一条链中有多少点的点权大于c 其中每秒操作点权++就是指我每操作一次 ...
- 主席树 ---- CF 1422F. Boring Queries(由离线推出在线如何求的 ,求解多次询问的区间LCM)
题目链接 题目大意: 给你nnn个数, 每次往第iii个数里面里面乘aaa,问你这nnn个数的LCM\text{LCM}LCM是多少? 解题思路: 多个数的lcm不是所有数的乘积除以所有数的gcd,如 ...
- 【CF464E】The Classic Problem(主席树+最短路)
点此看题面 大致题意: 给你一张无向图,每条边的边权为\(2^{x_i}\),求\(s\)到\(t\)的最短路. 最短路 最短路,首先考虑\(Dijkstra\).这里用\(SPFA\)似乎不太好,因 ...
- 【CodeForces】960 F. Pathwalks 主席树+动态规划
[题目]F. Pathwalks [题意]给定n个点m条边的有向图,可能不连通有重边有自环.每条边有编号 i 和边权 wi ,求最长的路径(可以经过重复节点)满足编号和边权都严格递增.n,m,wi&l ...
- COGS-257-动态排名系统-树状数组+主席树
描述 给定一个长度为N的已知序列A[i](1<=i<=N),要求维护这个序列,能够支持以下两种操作: 1.查询A[i],A[i+1],A[i+2],...,A[j](1<=i< ...
- BZOJ 3277 串 BZOJ 3473 字符串 (广义后缀自动机、时间复杂度分析、启发式合并、线段树合并、主席树)...
标签那么长是因为做法太多了... 题目链接: (bzoj 3277) https://www.lydsy.com/JudgeOnline/problem.php?id=3277 (bzoj 3473) ...
- BZOJ 3218 UOJ #77 A+B Problem (主席树、最小割)
BZOJ 3218 UOJ #77 A+B Problem (主席树.最小割) 大名鼎鼎的A+B Problem, 主席树优化最小割-- 调题死活调不对,一怒之下改了一种写法交上去A了,但是改写法之后 ...
最新文章
- Amazon DynamoDB 入门2:工作原理、API和数据类型介绍
- C语言与sqlserver数据库
- Java基础篇:static关键字
- 洛谷——P1068 分数线划定
- 红旗linux as4,可能是史上最完美的IC5141安装说明档(RHEL-AS4)
- 面向对象方法的优势简化软件开发的过程_Java面试题说一说你的对面向过程和面向对象的理解...
- HTML引用外部css 、js的路径
- 浅谈论文查重检测过程中的常见问题
- Modbus协议的PLC、智能仪表数据采集至SQL数据库,实现双向通讯
- VelocityTracker笔记
- 桌面组件开发学习笔记
- STM32开发环境安装
- GitHub、Apache 等平台开源项目,受美国出口管制么?
- Jenkins书籍推荐
- Python 京东抢购茅台脚本(亲测可用),github脚本24小时内删除
- 【NRF51822】DFU过程梳理
- 前端-HTML基础入门
- STM32--框架结构
- 蓄水池采样 Reservoir Sampling
- 蓝桥杯java历年真题及答案整理(共100道题目及答案)
热门文章
- 菜鸟学java ——(一)面向对象程序设计(几个重要的概念)
- python response.json()报错_python:解析requests返回的response(json格式)说明
- 用友t6怎么用文件服务器设置,用友T6库存管理选项设置:专用设置
- harbor安装_Harbor镜像仓库搭建
- oracle怎么设置sql每隔一段时间执行一次_Oracle大规模数据快速导出文本文件
- hadoop 开启防火墙_Hadoop部署一Hadoop安装
- Zabbix实战之客户端自动发现
- linux实时备份,51CTO博客-专业IT技术博客创作平台-技术成就梦想
- Applicatin、 server、 session 、cookies对象的简单使用方法
- Cache_总体介绍