bzoj4458: GTY的OJ

时间:2023-01-18 11:41:58

题目大意:给定一棵带点权的有根树,同时给定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&colon; GTY的OJ

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

  2. bzoj4458 GTY的OJ &lpar;优先队列&plus;倍增&rpar;

    把超级钢琴放到了树上. 这次不用主席树了..本来以为会好写一点没想到细节更多(其实是树上细节多) 为了方便,对每个点把他的那个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&period;10&period;29 NOIP2018模拟赛 解题报告

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

  6. NOIP2018赛前停课集训记(10&period;24~11&period;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. &lbrack;BZOJ3729&rsqb;Gty的游戏

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

随机推荐

  1. mysql 判断 字段是否为空

    SB.Append("select "); SB.Append("mpe.EVIDENCE_ID "); SB.Append("left join m ...

  2. 二模 (7) day2

    第一题: 题目大意:多重背包. 解题过程: 1.二进制拆分.最慢的点0.5s. 2.单调队列优化会更快,不过我不会.. 第二题: 题目描述:给定一个n×m的矩阵,记录左上角为(1,1),右下角为(n, ...

  3. RSA 加解密

    #region RSA public static byte[] GetBytes(String num) { BigInteger n = ); String s = n.ToString(); & ...

  4. Android(java)学习笔记108:通过反射获取私有构造方法并且使用

    反射获取私有构造方法并且使用: 1.获取字节码文件.class对象:          Class c = Class.forName("cn.itcast_01.Person") ...

  5. 知问前端--Ajax

    本节课主要是创建一个问题表,将提问数据通过 ajax 方式提交出去.然后对内容显示进行布局,实现内容部分隐藏和完整显示的功能. 一.Ajax 提问创建一个数据表:question,分别建立:id.ti ...

  6. zeromq源码分析笔记之架构(1)

    1.zmq概述 ZeroMQ是一种基于消息队列的多线程网络库,其对套接字类型.连接处理.帧.甚至路由的底层细节进行抽象,提供跨越多种传输协议的套接字.引用云风的话来说:ZeroMQ 并不是一个对 so ...

  7. Sea&period;Js的运行原理&lpar;转&rpar;

    1.CMD(Common Module Definition)规范 Sea.js采用了和Node相似的CMD规范,使用require.exports和module来组织模块.但Sea.js比起Node ...

  8. python-函数参数

    1.Python的函数定义非常简单,但灵活度却非常大.除了正常定义的必选参数外,还可以使用默认参数.可变参数和关键字参数,使得函数定义出来的接口,不但能处理复杂的参数,还可以简化调用者的代码 1).位 ...

  9. Java——类和对象

    前言   Java语言是一种面向对象的语言.面向对象的思想是在七十年代的时候由IBM的SmallTalk语言最先推广.那什么是面向对象呢?面向对象指的是一种开发模式.早期的计算机编程使用的是面向过程的 ...

  10. Laravel自带SMTP邮件组件实现发送邮件(QQ、163、企业邮箱都可)

    Laravel自带SMTP邮件组件实现发送邮件(QQ.163.企业邮箱都可)     laravel自带SMTP邮件配置和遇到的坑 laravel自带SwiftMailer库,集成了多种邮件API,可 ...