博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
P1552 [APIO2012]派遣
阅读量:4310 次
发布时间:2019-06-06

本文共 2823 字,大约阅读时间需要 9 分钟。

链接

思路

忍者数量肯定越多越好

那就从下到上的合并它的孩子
左偏树的话
顺便维护一个tot,大头堆,如果tot大于了m,把大的删掉
如果左偏树忘干净了或者没学的话
线段树合并也是个不错的选择
直接权值线段树合并就好,内存30倍会炸,也许是我没离散化的缘故吧
查询在线段树上面二分

左偏树代码

#include 
#define FOR(i,a,b) for(int i=a;i<=b;++i)#define ll long longusing namespace std;const int maxn=100047;inline int read() { int x=0,f=1;char s=getchar(); for(;s>'9'||s<'0';s=getchar()) if(s=='-') f=-1; for(;s>='0'&&s<='9';s=getchar()) x=x*10+s-'0'; return x*f;}struct edge { int v,nxt;}e[maxn];int head[maxn],tot;void add_edge(int u,int v) { e[++tot].v=v;e[tot].nxt=head[u];head[u]=tot;}int n,m,mone;ll sum[maxn],ans;int size[maxn];int ch[maxn][2],dis[maxn],val[maxn],xs[maxn];int work(int a,int b) { if(!a||!b) return a+b; if(val[a]
mone) rt=delet(rt); ans=max(ans,xs[u]*(ll)size[rt]); return rt;}int main() { n=read(),mone=read(); int root; FOR(i,1,n) { int x=read(); val[i]=read();xs[i]=read(); sum[i]=val[i];size[i]=1; if(x) add_edge(x,i); else root=i; } int wuyong=dfs(root); cout<
<<"\n"; return 0;}

线段树合并代码

#include 
#include
#include
#include
#include
#define ll long longusing namespace std;const int N=1e5+7;int read() { int x=0,f=1;char s=getchar(); for(;s>'9'||s<'0';s=getchar()) if(s=='-') f=-1; for(;s>='0'&&s<='9';s=getchar()) x=x*10+s-'0'; return x*f;}int n,m,money[N],leader[N],rt[N];vector
G[N];struct node { int l,r,siz; ll tot;}e[N*30];void pushup(int rt) { e[rt].siz=e[e[rt].l].siz+e[e[rt].r].siz; e[rt].tot=e[e[rt].l].tot+e[e[rt].r].tot;}int cnt;void insert(int l,int r,int L,int &rt) { rt=++cnt; if(l==r) { e[rt].siz++; e[rt].tot+=l; return; } int mid=(l+r)>>1; if(L<=mid) insert(l,mid,L,e[rt].l); else insert(mid+1,r,L,e[rt].r); pushup(rt);}int merge(int l,int r,int x,int y) { if(!x||!y) return x+y; if(l==r) { e[x].siz+=e[y].siz; e[x].tot+=e[y].tot; return x; } int mid=(l+r)>>1; e[x].l=merge(l,mid,e[x].l,e[y].l); e[x].r=merge(mid+1,r,e[x].r,e[y].r); pushup(x); return x;}int query(int l,int r,int k,int rt) { if(l==r) return k>=e[rt].tot ? e[rt].siz : 0; int mid=(l+r)>>1; if(e[e[rt].l].tot>=k) return query(l,mid,k,e[rt].l); else return e[e[rt].l].siz+query(mid+1,r,k-e[e[rt].l].tot,e[rt].r);}ll ans;void dfs(int u) { insert(1,1000000000,money[u],rt[u]); for(vector
::iterator it=G[u].begin();it!=G[u].end();++it) { dfs(*it); rt[u]=merge(1,1000000000,rt[u],rt[*it]); } ans=max(ans,(ll)leader[u]*query(1,1000000000,m,rt[u]));}int main() { n=read(),m=read(); for(int i=1;i<=n;++i) { int x=read(); money[i]=read(); leader[i]=read(); G[x].push_back(i); } dfs(1); printf("%lld",ans); return 0;}

转载于:https://www.cnblogs.com/dsrdsr/p/10359546.html

你可能感兴趣的文章
Python 集合
查看>>
几本关于PHP安全的书
查看>>
学习记录--HooKSystemCall
查看>>
使用apache设置绑定多个域名或网站
查看>>
bzoj2194: 快速傅立叶之二
查看>>
2018-2019-2 20189206 《密码与安全新技术专题》 第四次作业
查看>>
CentOS7如何设置静态IP及开放DNS端口
查看>>
精密V / I 转换电路
查看>>
求组合数取模的几种方法
查看>>
个人所得税计算器
查看>>
vs2015 不能启动 iis express
查看>>
electron 写入注册表 实现开机自启动
查看>>
记一次Debug过程
查看>>
画圆算法
查看>>
记录一次redis故障
查看>>
最近公共祖先(lca) hdu 2586
查看>>
安卓开发笔记——关于AsyncTask的使用
查看>>
spout详解
查看>>
一个md5加密的工具类,用的虚拟机的包,不需要额外导包
查看>>
centos7在VMware下配置网络连接
查看>>