题目大意:给定一棵带点权的有根树,同时给定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. iOS之UIApplication详解

    UIApplication对象特点: 特点1: UIApplication对象是应用程序的象征,一个UIApplication对象就代表一个应用程序,而且是单例的.(用来封装整个应用程序的一个对象, ...

  2. JVM-内存管理

    都说搞C的牛叉,那是因为C解决问题,全靠程序员自己,他们对自己的程序在内存中是什么样了如指掌.而Java呢不需要有太多操作系统的知识,不用时刻注意内存的问题,但这不代表我们就不用去了解它背后的原理.J ...

  3. Openstack api 学习文档 & restclient使用文档

    Openstack api 学习文档 & restclient使用文档 转载请注明http://www.cnblogs.com/juandx/p/4943409.html 这篇文档总结一下我初 ...

  4. Windows下使用Xshell建立反向隧道

    反向隧道是一个进行内网穿透的简单而有用的方法.在Linux下通过OpenSSH和AutoSSH可以很容易地建立稳定的反向隧道.但是在Windows下,还能看到有人特意装个Cygwin来运行这些工具…… ...

  5. ORACLE外部表总结

    外部表介绍 ORACLE外部表用来存取数据库以外的文本文件(Text File)或ORACLE专属格式文件.因此,建立外部表时不会产生段.区.数据块等存储结构,只有与表相关的定义放在数据字典中.外部表 ...

  6. JAVA Map

    基本特性: 维持健值对的集合接口,健不可以重复,每一个健只能映射到一个值. Map替代了原来的虚拟类Directory. Map提供了三种集合视角,keys(KeySet),values(Values ...

  7. 记录sql语句的执行记录,用于分析

    SET STATISTICS PROFILE ONSET STATISTICS IO ONSET STATISTICS TIME ONGO --这之间是要执行的脚本select * from [Use ...

  8. CentOS安装LNMP环境的基础组件

    注:以下所有操作均在CentOS 6.5 x86_64位系统下完成. 在安装LNMP环境之前,请确保已经使用yum安装了以下各类基础组件(如果系统已自带,还可以考虑yum update下基础组件): ...

  9. android xml 布局错误

    最近重新安装了下android开发环境,发现在调整页面的时候 ,老是报以下错误,导致无法静态显示ui效果. Missing styles. Is the correct theme chosen fo ...

  10. [python]爬虫学习(一)

    要学习Python爬虫,我们要学习的共有以下几点(python2): Python基础知识 Python中urllib和urllib2库的用法 Python正则表达式 Python爬虫框架Scrapy ...