正题

题目链接:https://www.luogu.com.cn/problem/P6847


题目大意

\(n\)个点的一棵树上,每个时刻可以割掉一些边,一些节点上有果实表示如果在\(d_i\)时刻这个点恰好不与\(1\)联通,那么就可以获得\(w_i\)的价值。

\(1\leq n,k\leq 10^5\)


解题思路

设\(f_{x,i}\)表示节点\(x\)在时刻\(i\)之前割掉时的最大权值那么相当与在儿子里面选一个最大的\(f_{y,j}(j\leq i)\)合并上来。

这是一个很经典的转移方式,和命运那题一样,直接用线段树合并维护就好了。

时间复杂度\(O(n\log k)\)


code

#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const ll N=1e5+10;
ll n,m,k,rt[N],fa[N],d[N],w[N];
ll cnt,t[N<<5],lazy[N<<5],ls[N<<5],rs[N<<5];
void Downdata(int x){
if(!lazy[x])return;
if(ls[x])lazy[ls[x]]+=lazy[x],t[ls[x]]+=lazy[x];
if(rs[x])lazy[rs[x]]+=lazy[x],t[rs[x]]+=lazy[x];
lazy[x]=0;return;
}
void Change(ll &x,ll L,ll R,ll pos,ll val,ll z){
if(!x)x=++cnt;
if(L==R){t[x]=val+max(z,t[x]);return;}
ll mid=(L+R)>>1;Downdata(x);
if(pos<=mid)Change(ls[x],L,mid,pos,val,z);
else Change(rs[x],mid+1,R,pos,val,max(z,t[ls[x]]));
t[x]=max(t[ls[x]],t[rs[x]]);
return;
}
ll Merge(ll L,ll R,ll x,ll y,ll mx1,ll mx2){
if(!x||!y){
if(x)lazy[x]+=mx2,t[x]+=mx2;
if(y)lazy[y]+=mx1,t[y]+=mx1;
return x|y;
}
if(L==R){t[x]=max(t[x],mx1)+max(t[y],mx2);return x;}
ll mid=(L+R)>>1;Downdata(x);Downdata(y);
rs[x]=Merge(mid+1,R,rs[x],rs[y],max(mx1,t[ls[x]]),max(mx2,t[ls[y]]));
ls[x]=Merge(L,mid,ls[x],ls[y],mx1,mx2);
t[x]=max(t[ls[x]],t[rs[x]]);
return x;
}
signed main()
{
scanf("%lld%lld%lld",&n,&m,&k);
for(ll i=2;i<=n;i++)
scanf("%lld",&fa[i]);
for(ll i=1;i<=m;i++){
ll x;scanf("%lld",&x);
scanf("%lld%lld",&d[x],&w[x]);
}
for(ll x=n;x>=1;x--){
if(d[x])Change(rt[x],1,k,d[x],w[x],0);
if(fa[x])rt[fa[x]]=Merge(1,k,rt[fa[x]],rt[x],0,0);
}
printf("%lld\n",t[rt[1]]);
return 0;
}

P6847-[CEOI2019]Magic Tree【dp,线段树合并】的更多相关文章

  1. BZOJ_2212_[Poi2011]Tree Rotations_线段树合并

    BZOJ_2212_[Poi2011]Tree Rotations_线段树合并 Description Byteasar the gardener is growing a rare tree cal ...

  2. 【pkuwc2018】 【loj2537】 Minmax DP+线段树合并

    今年年初的时候参加了PKUWC,结果当时这一题想了快$2h$都没有想出来.... 哇我太菜啦.... 昨天突然去搜了下哪里有题,发现$loj$上有于是就去做了下. 结果第一题我5分钟就把所有细节都想好 ...

  3. 【BZOJ2212】[Poi2011]Tree Rotations 线段树合并

    [BZOJ2212][Poi2011]Tree Rotations Description Byteasar the gardener is growing a rare tree called Ro ...

  4. [BZOJ5461][LOJ#2537[PKUWC2018]Minimax(概率DP+线段树合并)

    还是没有弄清楚线段树合并的时间复杂度是怎么保证的,就当是$O(m\log n)$吧. 这题有一个显然的DP,dp[i][j]表示节点i的值为j的概率,转移时维护前缀后缀和,将4项加起来就好了. 这个感 ...

  5. bzoj2212[Poi2011]Tree Rotations [线段树合并]

    题面 bzoj ans = 两子树ans + min(左子在前逆序对数, 右子在前逆序对数) 线段树合并 #include <cstdio> #include <cstdlib> ...

  6. BZOJ2212 [Poi2011]Tree Rotations 线段树合并 逆序对

    原文链接http://www.cnblogs.com/zhouzhendong/p/8079786.html 题目传送门 - BZOJ2212 题意概括 给一棵n(1≤n≤200000个叶子的二叉树, ...

  7. BZOJ.5461.[PKUWC2018]Minimax(DP 线段树合并)

    BZOJ LOJ 令\(f[i][j]\)表示以\(i\)为根的子树,权值\(j\)作为根节点的概率. 设\(i\)的两棵子树分别为\(x,y\),记\(p_a\)表示\(f[x][a]\),\(p_ ...

  8. BZOJ.2212.[POI2011]Tree Rotations(线段树合并)

    题目链接 \(Description\) 给定一棵n个叶子的二叉树,每个叶节点有权值(1<=ai<=n).可以任意的交换两棵子树.问最后顺序遍历树得到的叶子权值序列中,最少的逆序对数是多少 ...

  9. LOJ2537. 「PKUWC2018」Minimax【概率DP+线段树合并】

    LINK 思路 首先暴力\(n^2\)是很好想的,就是把当前节点概率按照权值大小做前缀和和后缀和然后对于每一个值直接在另一个子树里面算出贡献和就可以了,注意乘上选最大的概率是小于当前权值的部分,选最小 ...

随机推荐

  1. 进程上下文&中断上下文

    文章出自http://hi.baidu.com/bkhcvzdvmjfkpyr/item/5444001fa68d065bf1090ea6 处理器总处于以下状态中的一种: 1.内核态,运行于进程上下文 ...

  2. ThreadLocal 的应用

    ThreadLocal set() 的只能是当前线程能使用的值 public class TestTreadLocal{ public static final ThreadLocal threadS ...

  3. ajax无法返回视图

    $.ajax({ url:"http://localhost:8080/wb/toUpLoad", type:"post", data:formData, pr ...

  4. 24点游戏(24 game)的C++编程求解实现

    什么是24点游戏 24点游戏,英文叫做24 game,是对给定的4个非负整数进行加减乘除运算,要求每个数都要被用到且仅用到一次,并得到最终的运算结果为24.比如3.8.3.8这四个数,可以找出唯一的一 ...

  5. Mybatis-plus<一> Springboot框架使用MybatisPlus代码自动生成器

    Mybatis-plus<一> Springboot框架使用MybatisPlus代码自动生成器 Mybatis-plus官网: https://mp.baomidou.com/ Demo ...

  6. SQLServer数据实时同步PostgreSQL

    SQLServer数据实时同步至PostgreSQL 前言: 为迎合工作需求有时候传送的数据保存在SQLServer中但由于工作需要需要保存到PostgreSQL中进行处理,本文主要通过在SQLSer ...

  7. sql常用查询命令

    目录 SQL Server常用查询命令: 查看当前时间 查询所有数据库名 查询当前使用的数据库名 查询前几条数据 去重查询 字段换名 查询不等于 查询在两个值之间数据 查询条件或 模糊匹配查询 查询为 ...

  8. Linux原始套接字抓取底层报文

    1.原始套接字使用场景 我们平常所用到的网络编程都是在应用层收发数据,每个程序只能收到发给自己的数据,即每个程序只能收到来自该程序绑定的端口的数据.收到的数据往往只包括应用层数据,原有的头部信息在传递 ...

  9. GIT:创建、查看分支命令(git branch -vv)

    在开发过程中一般会用到Git进行版本管理,创建查看分支并与远程仓库交互是非常常见的操作. branch分支 是指在开发主线中分离出来的,做进一步开发而不影响到原来的主线. Git存储的不是一系列的更改 ...

  10. 使用dubbo-go搭建dubbo接口测试平台

    背景 http接口测试只需要一个curl命令,但dubbo协议没有这样的现成接口测试工具.通常公司内的dubbo控制台或其他平台会集成一个dubbo接口测试工具. 调用一个dubbo接口,需要知道服务 ...