洛谷 P1552 [APIO2012] 派遣 题解
算法:线段树合并,离散化。
考虑任意一点 为领导者的情况。
显然,选出以 为根的子树中薪水 最少的 个结点(忍者),满足 的情况下使 尽可能大,这样 为领导者的最大满意度为 。
考虑如何高效地求出每个点为领导时可以派遣的忍者的最大数量。
可以想到线段树:我们先离散化,对于每个点 求出 的排名 。把这些都存到一棵以 为下标的线段树上,由于离散化后满足单调性,我们只需要在线段树上二分一下就能得出答案。
那么如何建出这样一棵线段树呢?
不难想到线段树合并:我们对于每一个忍者 (包含 Master)都开一棵线段树,然后插入 。每次从叶子结点向根结点通过树上二分求出当前点为领导者时能派遣的忍者的最大数两,然后将当前忍者的线段树合并到这个忍者上级的线段树上。
时间复杂度 。
/* * Title: P1552 [APIO2012] 派遣 * Source: Luogu * URL: https://www.luogu.com.cn/problem/P1552 * Author: Steven_lzx * Command: -std=c++23 -Wall -fno-ms-extensions * Date: 2022.10.19 */ #include <iostream> #include <cstdio> #include <algorithm> #include <utility> using namespace std; typedef long long ll; const int MAXN=100010; struct Segt { int ls,rs,cnt; ll sum; }tr[MAXN<<5]; int idx,root[MAXN],n,m,b[MAXN],c[MAXN]; ll l[MAXN],ans; pair<int,int> t[MAXN]; void update(int p,int l,int r,int k,int c) { int mid; tr[p].cnt++; tr[p].sum+=c; if(l==r) return; mid=(l+r)>>1; if(k<mid) { if(!tr[p].ls) tr[p].ls=++idx; update(tr[p].ls,l,mid,k,c); } else { if(!tr[p].rs) tr[p].rs=++idx; update(tr[p].rs,mid+1,r,k,c); } } int query(int p,int l,int r,int k) { int mid; if(!p) return 0; if(l==r) { if(tr[p].sum<=k) return 1; return 0; } mid=(l+r)>>1; if(tr[tr[p].ls].sum<k) return tr[tr[p].ls].cnt+query(tr[p].rs,mid+1,r,k-tr[tr[p].ls].sum); return query(tr[p].ls,l,mid,k); } void merge(int &p,int q) { if(!p||!q) { tr[p+q].cnt=tr[p].cnt+tr[q].cnt; tr[p+q].sum=tr[p].sum+tr[q].sum; p+=q; return; } merge(tr[p].ls,tr[q].ls); merge(tr[p].rs,tr[q].rs); tr[p].cnt=tr[tr[p].ls].cnt+tr[tr[p].rs].cnt; tr[p].sum=tr[tr[p].ls].sum+tr[tr[p].rs].sum; return; } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { scanf("%d%d%lld",b+i,c+i,l+i); t[i]=make_pair(c[i],i); } stable_sort(t+1,t+n+1); for(int i=1,k;i<=n;i++) { root[k=t[i].second]=++idx; update(root[k],1,n+1,i,c[k]); } for(int i=n;i;i--) { ans=max(ans,l[i]*query(root[i],1,n+1,m)); if(b[i]) merge(root[b[i]],root[i]); } printf("%lld\n",ans); return 0; }
本文作者:Day_Dreamer_D's Blog
本文链接:https://www.cnblogs.com/2020gyk080/p/16807381.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
分类:
标签:
,
,
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步