题目大意:给定一棵带点权的有根树,同时给定L,R,要求找M条链,每条链满足以下条件的情况下,要求所有链权和最大:

1、两两不相同(可以包含/相交等)

2、节点数在[L,R]间

3、其中一个端点的深度必须是整条链所有点深度的最小值(原谅我实在不会表达……)(形象地说,就是直上直下)


感觉和NOI某原题什么钢琴有点像

当一条链的下端点确定时,上端点的选择范围就是一条链,也就是说,我们可以求出每个点到根的点权和val[u]存入主席树,这样就可以求 以指定点为下端点 权第k大的链了。

用堆来维护 所有下端点当前权最大的链,每取出一个当前最大值,假设它是其下端点权第k大的链,就在主席树里找这个下端点权第k+1大的链

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <queue>
#define ll long long
#define N 500005
#define M 500005
#define INF (1e9) using namespace std;
inline int read(){
int ret=0;char ch=getchar();
bool flag=0;
while (ch<'0'||ch>'9'){
flag=ch=='-';
ch=getchar();
}
while ('0'<=ch&&ch<='9'){
ret=ret*10-48+ch;
ch=getchar();
}
return flag?-ret:ret;
} int n;
int fa[N],f[N][22],fl[N],fr[N],deep[N];
int a[N],val[N];
int need,L,R;
int root[N]; void init(){
n=read()+1;fa[2]=read()+1;
for (int i=3;i<=n;++i) fa[i]=read()+1;
for (int i=2;i<=n;++i) a[i]=read();
fa[1]=a[1]=0;
need=read();L=read();R=read()+1;//interval->[L,R)
} struct SegmentTree{
struct STnode{
int sum,ls,rs;
} t[N*33];
int size;
void clear(){size=t[0].sum=t[0].ls=t[0].rs=0;}
void modify(int &x,int L,int R,int pos){
t[++size]=t[x];
x=size;
++t[x].sum;
if (L==R) return;
int mid=(L+R)/2;
if (L+R<0) --mid;
if (pos<=mid) modify(t[x].ls,L,mid,pos);
else modify(t[x].rs,mid+1,R,pos);
}
int qmink(int x,int y,int L,int R,int k){
if (L==R) return L;
int tmp=t[t[x].ls].sum-t[t[y].ls].sum,mid=(L+R)/2;
if (L+R<0) --mid;
if (k<=tmp) return qmink(t[x].ls,t[y].ls,L,mid,k);
else return qmink(t[x].rs,t[y].rs,mid+1,R,k-tmp);
}
} st; void precompute(){
val[0]=a[0]=deep[0]=fa[0]=0;
for (int i=1;i<=n;++i){
val[i]=val[fa[i]]+a[i];
deep[i]=deep[fa[i]]+1;
f[i][0]=fa[i];
}
memset(f[0],0,sizeof(f[0]));
for (int k=1;k<=20;++k)
for (int i=1;i<=n;++i)
f[i][k]=f[f[i][k-1]][k-1]; st.clear();root[0]=0;
for (int i=1;i<=n;++i){
fl[i]=fr[i]=i;
for (int k=0;k<=20;++k){
if ((L&(1<<k))>0) fl[i]=f[fl[i]][k];
if ((R&(1<<k))>0) fr[i]=f[fr[i]][k];
} st.modify(root[i]=root[fa[i]],-INF,INF,val[i]);
}
} struct HeapNode{
int pos,value,k;
HeapNode(){}
HeapNode(int _pos,int _value,int _k):pos(_pos),value(_value),k(_k){}
};
inline bool operator <(const HeapNode &u,const HeapNode &v){
return u.value<v.value;
}
priority_queue<HeapNode> h; void work(){
while (!h.empty()) h.pop();
for (int i=1;i<=n;++i)
if (deep[fl[i]]-deep[fr[i]])
h.push(HeapNode(i,val[i]-st.qmink(root[fl[i]],root[fr[i]],-INF,INF,1),1));
ll ans=0;
while (need--){
HeapNode now=h.top();
h.pop();
ans+=(ll)now.value;
int u=fl[now.pos],v=fr[now.pos];
if (deep[u]-deep[v]>now.k)
h.push(HeapNode(now.pos,val[now.pos]-st.qmink(root[u],root[v],-INF,INF,now.k+1),now.k+1));
}
printf("%lld\n",ans);
} int main(){
init();
precompute();
work();
return 0;
}

  

bzoj4458: GTY的OJ的更多相关文章

  1. 【贪心 计数 倍增】bzoj4458: GTY的OJ

    倍增写挂调了半个晚上 Description 身为IOI金牌的gtyzs有自己的一个OJ,名曰GOJ.GOJ上的题目可谓是高质量而又经典,他在他的OJ里面定义了一个树形的分类目录,且两个相同级别的目录 ...

  2. bzoj4458 GTY的OJ (优先队列+倍增)

    把超级钢琴放到了树上. 这次不用主席树了..本来以为会好写一点没想到细节更多(其实是树上细节多) 为了方便,对每个点把他的那个L,R区间转化成两个深度a,b,表示从[a,b)选一个最小的前缀和(到根的 ...

  3. 【BZOJ4458】GTY的OJ

    题面 Description 身为IOI金牌的gtyzs有自己的一个OJ,名曰GOJ.GOJ上的题目可谓是高质量而又经典,他在他的OJ里面定义了一个树形的分类目录,且两个相同级别的目录是不会重叠的.比 ...

  4. 【BZOJ4458】GTY的OJ(树上超级钢琴)

    点此看题面 大致题意: 给你一棵树,让你求出每一个节点向上的长度在\([l,r]\)范围内的路径权值和最大的\(m\)条路径的权值总和. 关于此题的数列版本 此题的数列版本,就是比较著名的[BZOJ2 ...

  5. 2018.10.29 NOIP2018模拟赛 解题报告

    得分: \(70+60+0=130\)(\(T3\)来不及打了,结果爆\(0\)) \(T1\):简单的求和(点此看题面) 原题: [HDU4473]Exam 这道题其实就是上面那题的弱化版,只不过把 ...

  6. NOIP2018赛前停课集训记(10.24~11.08)

    前言 为了不久之后的\(NOIP2018\),我们的停课从今天(\(Oct\ 24th\))起正式开始了. 本来说要下周开始的,没想到竟提早了几天,真是一个惊喜.毕竟明天有语文考试.后天有科学考试,逃 ...

  7. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  8. Online Judge(OJ)搭建(第一版)

    搭建 OJ 需要的知识(重要性排序): Java SE(Basic Knowledge, String, FileWriter, JavaCompiler, URLClassLoader, Secur ...

  9. [BZOJ3729]Gty的游戏

    [BZOJ3729]Gty的游戏 试题描述 某一天gty在与他的妹子玩游戏.妹子提出一个游戏,给定一棵有根树,每个节点有一些石子,每次可以将不多于L的石子移动到父节点,询问将某个节点的子树中的石子移动 ...

随机推荐

  1. Android内存泄漏

    Java是垃圾回收语言的一种,其优点是开发者无需特意管理内存分配,降低了应用由于局部故障(segmentation fault)导致崩溃,同时防止未释放的内存把堆栈(heap)挤爆的可能,所以写出来的 ...

  2. Android编码规范04

    private final String MESSAGE_WARN = "您输入的密码有误,请重新输入!"; private final String CLASS_ONE = &q ...

  3. iOS 疑难杂症 — — 推送本地国际化 loc-key 本地化失败的问题

    声明  欢迎转载,但请保留文章原始出处:)  博客园:http://www.cnblogs.com 农民伯伯: http://over140.cnblogs.com 正文 一.准备 推送本地国际化官方 ...

  4. popupwindow展示

    样式: layout: popup_appinfo.xml <?xml version="1.0" encoding="utf-8"?> <L ...

  5. ORACLE 9i 数据库体系结构图

    ORACLE 9i 的数据库体系结构图,非常的全面.系统.高屋建瓴的整体介绍了ORACLE 9i 的数据库体系结构.如果能全面了解.清晰梳理.深入掌握这些知识点,相信对你了解学习.深入研究ORACLE ...

  6. Oracle Linux 5.7安装VMware Tools的问题

    案例环境介绍:     虚拟机的版本:VMware® Workstation 8.0.3 build-703057    操作系统版本:Oracle Linux Server release 5.7 ...

  7. Hadoop日常维护系列——Hadoop添加删除节点

    添加节点 1.修改host    和普通的datanode一样.添加namenode的ip 2.修改namenode的配置文件conf/slaves    添加新增节点的ip或host 3.在新节点的 ...

  8. [有意思]The IT workers of Star Wars -- That's not a bug. It's a feature

    Yeah, that Artoo is kinda mouthy... ... now select, "restore to factory settings." That'll ...

  9. javascrip中parentNode和offsetParent之间的区别

    首先是 parentNode 属性,这个属性好理解,就是在 DOM 层次结构定义的上下级关系,如果元素A包含元素B,那么元素B就可以通过 parentElement 属性来获取元素A. 要明白 off ...

  10. JavaScript 基础回顾——函数

    在JavaScript中,函数也是一种数据类型,属于 function 类型,所以使用Function关键字标识函数名.函数可以在大括号内编写代码并且被调用,作为其他函数的参数或者对象的属性值. 1. ...