倍增写挂调了半个晚上

Description

身为IOI金牌的gtyzs有自己的一个OJ,名曰GOJ。GOJ上的题目可谓是高质量而又经典,他在他的OJ里面定义了一个树形的分类目录,且两个相同级别的目录是不会重叠的。比如图论的大目录下可能分为最短路,最小生成树,网络流等低一级的分类目录,这些目录下可能还有更低一级的目录,以此类推。现在gtyzs接到了一个任务,要他为SDTSC出题。他准备在自己的OJ题库中找出M道题作为SDTSC的试题,而他深知SDTSC的童鞋们个个都是神犇,所以gtyzs认为自己出的这M道题中,每道题都应该属于不少于L种分类目录;可他又怕自己的题没有人会做,所以每道题也应该属于不超过R种分类目录,并且这些分类目录应该是连续的,不能出现断层。对了,最重要的是,不存在一道题,它属于两个分类目录且这两个目录不是包含关系。(比如不存在一道题它既是一道DP题,又是一道网络流题)gtyzs怕被骂,所以他希望不存在任意的一对题目(u,v),使得u所属的分类目录与v完全相同。举例来说,gtyzs不能出两道同样的都是动态规划,背包的题,但是却可以出一道属于动态规划,背包和01背包的题和一道属于背包,01背包的题,当然也可以出一个属于图论的题和一个属于数论的题。(注意:一道题所属的分类目录不一定从根开始,如加粗部分所示)
为了让自己的题目变得更加靠谱,他给每一个分类目录都定了一个靠谱值ai,这个值可正可负。一道题的靠谱度为其从属的分类目录靠谱值的加和。我们假设动态规划的靠谱值为10,插头DP的靠谱值为-5,则一道动态规划插头DP的题的靠谱值就是5。gtyzs希望自己出的这M道题,在满足上述前提条件下,靠谱度总和最大。gtyzs当然会做啦,于是你就看到了这个题。

Input

输入的第一行是一个正整数N,代表分类目录的总数。
接下来的一行,共N个正整数,第i个正整数为fi,表示分类目录i被fi所包含。保证一个分类目录只会被一个分类目录所包含,且包含关系不存在环。特别的,fi=0表示它是根节点,我们保证这样的点只存在一个。
接下来的一行,共N个整数,第i个数表示ai。
最后一行,三个正整数M,L,R。
对于100%的数据,1≤N≤500,000,1≤M≤500,000,|ai|≤2,000。保证输入数据有解。
为了方便,所有的测试数据中都有f1=0,且对于任意的i∈[2,N],有fi<i。

Output

一行一个整数,表示最大的靠谱度。

Sample Input

7
0 1 1 2 2 3 3
2 3 4 1 2 3 4
3 3 3

Sample Output

26

题目分析

树上超级钢琴,配合bzoj2006: [NOI2010]超级钢琴食用更佳。

思路几乎一模一样,不过是应用了一些树与序列不同的性质去做这个事情:前缀和上树;倍增维护点$u$至$2^i$个祖先上路径$sum_i$最小值。有些±1的细节可能需要好好注意。

倍增还不够熟练

 #include<bits/stdc++.h>
typedef long long ll;
typedef std::pair<ll, int> pr;
const int maxn = ;
const int maxm = ; ll ans;
pr st[maxn][];
int fa[maxn][],dep[maxn];
int n,m,L,R,w[maxn],s[maxn];
int edgeTot,head[maxn],nxt[maxm],edges[maxm];
struct node
{
int u,l,r,p;
ll w;
pr query(int x, int d)
{
pr ret = pr(s[x],x);
for (int i=; i>=; i--)
if ((d>>i)&) ret = std::min(ret, st[x][i]), x = fa[x][i];
return ret;
}
int findFa(int x, int d)
{
for (int i=; i>=; i--)
if ((d>>i)&) x = fa[x][i];
return x;
}
void calc()
{
int fa = findFa(u, l);
pr tmp = query(fa, r-l);
w = s[u]-tmp.first;
p = dep[u]-dep[tmp.second]; }
node(int a, int b, int c):u(a),l(b),r(c) {}
bool operator < (node a) const
{
return w < a.w;
}
};
std::priority_queue<node> q; int read()
{
char ch = getchar();
int num = ;
bool fl = ;
for (; !isdigit(ch); ch=getchar())
if (ch=='-') fl = ;
for (; isdigit(ch); ch=getchar())
num = (num<<)+(num<<)+ch-;
if (fl) num = -num;
return num;
}
void addedge(int u, int v)
{
if (!u) return;
fa[v][] = u, edges[++edgeTot] = v, nxt[edgeTot] = head[u], head[u] = edgeTot;
}
void init()
{
for (int i=; i<=n; i++)
s[i] += s[fa[i][]]+w[i], dep[i] = dep[fa[i][]]+;
for (int j=; j<=; j++)
for (int i=; i<=n; i++)
fa[i][j] = fa[fa[i][j-]][j-];
for (int i=; i<=n; i++) st[i][] = pr(s[fa[i][]], fa[i][]);
for (int j=; j<=; j++)
for (int i=; i<=n; i++)
st[i][j] = std::min(st[i][j-], st[fa[i][j-]][j-]);
}
int main()
{
memset(head, -, sizeof head);
n = read();
for (int i=; i<=n; i++) addedge(read(), i);
for (int i=; i<=n; i++) w[i] = read();
m = read(), L = read(), R = read();
init();
for (int i=; i<=n; i++)
{
if (dep[i] < L) continue;
int l = L, r = std::min(dep[i], R);
if (l <= r){
node tmp = node(i, l, r);
tmp.calc(), q.push(tmp);
}
}
while (m--)
{
if (q.empty()) break;
node tt = q.top();
q.pop(), ans += tt.w;
int u = tt.u, l = tt.l, r = tt.r, p = tt.p;
if (l < p){
node tmp = node(u, l, p-);
tmp.calc(), q.push(tmp);
}
if (r > p){
node tmp = node(u, p+, r);
tmp.calc(), q.push(tmp);
}
}
printf("%lld\n",ans);
return ;
}

END

【贪心 计数 倍增】bzoj4458: GTY的OJ的更多相关文章

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

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

  2. bzoj4458: GTY的OJ

    题目大意:给定一棵带点权的有根树,同时给定L,R,要求找M条链,每条链满足以下条件的情况下,要求所有链权和最大: 1.两两不相同(可以包含/相交等) 2.节点数在[L,R]间 3.其中一个端点的深度必 ...

  3. Luogu 1084 NOIP2012 疫情控制 (二分,贪心,倍增)

    Luogu 1084 NOIP2012 疫情控制 (二分,贪心,倍增) Description H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树, 1 号城市是首都, 也是 ...

  4. 【BZOJ4458】GTY的OJ

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

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

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

  6. BZOJ1178 APIO2009 会议中心 贪心、倍增

    传送门 只有第一问就比较水了 每一次贪心地选择当前可以选择的所有线段中右端点最短的,排序之后扫一遍即可. 考虑第二问.按照编号从小到大考虑每一条线段是否能够被加入.假设当前选了一个区间集合\(T\), ...

  7. Luogu1084 NOIP2012D2T3 疫情控制 二分答案、搜索、贪心、倍增

    题目传送门 题意太长就不给了 发现答案具有单调性(额外的时间不会对答案造成影响),故考虑二分答案. 贪心地想,在二分了一个时间之后,军队尽量往上走更好.所以我们预处理倍增数组,在二分时间之后通过倍增看 ...

  8. [CF1059E]Split the Tree[贪心+树上倍增]

    题意 给定 \(n\) 个节点的树,点有点权 \(w\) ,划分成多条儿子到祖先的链,要求每条链点数不超过 \(L\) ,和不超过 \(S\),求最少划分成几条链. \(n\leq 10^5\) . ...

  9. CF1190E Tokitsukaze and Explosion 二分、贪心、倍增、ST表

    传送门 最小值最大考虑二分答案,不难发现当最小值\(mid\)确定之后,原点到所有直线的距离一定都是\(mid\)时才是最优的,也就是说这些直线一定都是\(x^2+y^2=mid^2\)的切线. 接下 ...

随机推荐

  1. 如何使用WPS从正文开始页码为1,而不是从目录开始?

    在插入目录前,在最前页插入一个空白页,在这个空白页里面生成目录,双击正文的页脚,点一下出现的与上一节相同的按钮,关闭页眉页脚的同前节,发现与上一节相同这几个字消失后,把目录中的页码删除,不会在影响正文 ...

  2. Arrange the Bulls

    题目链接 #include <stdio.h> #include <algorithm> #include <string.h> #include <iost ...

  3. Centos下安装pip失败或新装

    Centos安装pip失败: [root@localhost /]# yum -y install pip已加载插件:fastestmirrorRepodata is over 2 weeks old ...

  4. D-温暖的签到题

    链接:https://ac.nowcoder.com/acm/contest/892/D 题意: 给你一个长度为n的序列,初始为1,2,3...n,对其进行m次操作. 操作有两种: 1 l r  表示 ...

  5. bzoj3159决战 码农题 树剖套splay

    最近沉迷码农题无法自拔 首先有一个暴力的想法:对于每个重链维护一个splay,需要翻转的连起来,翻转,接回去 然后发现这样没问题... 一条链只能跨log个重链,也就只有log个splay的子树参与重 ...

  6. CountDownLatch MyUncaughtExceptionHandler

    package com.yd.wmsc.util; import java.text.SimpleDateFormat; import java.util.Date; import java.util ...

  7. docker 开启remote api

    docker官方文档上有相关说明(Configure and run Docker on various distributions),ubuntu上是可行的 sudo vi /etc/default ...

  8. 为什么数据库ID不能作为URL中的标识符

    最近公司在进行网站的SEO优化,将所有主要页面的URL统一更改为新的格式,其中重要的一项改变是将所有URL的标识符统一为ID,例如过去我们的一个用户的公共页面URL是这样的 https://www.e ...

  9. HubbleDotNet 使用类

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using Hubble.S ...

  10. File类。

    File类: java.io.File 类.是文件和文件夹目录名的抽象表示形式. 可以用File对文件和文件夹进行 创建,删除,获取等操作. File类的一些静态成员变量: static String ...