uoj#418. 【集训队作业2018】三角形(线段树合并)
好迷啊……膜一下ljz
考虑每个操作,如果把操作按先后顺序放到序列上的话,操作一就是把\(w_i\)的石子放到某个节点,那么就是在序列末端加入\(w_i\),然后根据贪心肯定要把它所有儿子的石子拿走,也就是要减去\(\sum w_{son}\)
那么每个点的答案就是序列的最大前缀
因为父亲节点的操作一要在儿子之后进行,很麻烦,那么可以每次在自己这里把\(w_i\)减掉,到父亲的时候再加回去
记\((x,y)\)为一个二元组,\(x\)表示当前位置的最大前缀和,\(y\)表示最小后缀和,然后定义一个运算\((ax,by)=(x+max(0,a+y),b+min(0,a+y)\),大概能看出是个什么东西,注意这个运算不满足交换律
然后考虑一下这些二元组在序列中的顺序,如果\(x+y<0\),那么肯定得放前面,因为可以让之后的前缀和减小。
那么当\(x+y<0\)时,按\(x\)排序,这样能使前缀和不断减小。如果\(x+y>0\),按\(y\)排序就好了
维护二元组的话,用线段树合并,如果当前二元组的\(x+y<0\)且有比它最大前缀大的二元组,那么就已经是最优的了否则将在它前面的二元组与它合并,合并完后加进线段树里就好了。注意合并完之后节点没了要记得清空
//minamoto
#include<bits/stdc++.h>
#define R register
#define int long long
#define loli 200000000000000
#define fp(i,a,b) for(R int i=a,I=b+1;i<I;++i)
#define fd(i,a,b) for(R int i=a,I=b-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
using namespace std;
char buf[1<<21],*p1=buf,*p2=buf;
inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
int read(){
R int res,f=1;R char ch;
while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
return res*f;
}
char sr[1<<21],z[20];int C=-1,Z=0;
inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
void print(R int x){
if(C>1<<20)Ot();if(x<0)sr[++C]='-',x=-x;
while(z[++Z]=x%10+48,x/=10);
while(sr[++C]=z[Z],--Z);sr[++C]=' ';
}
const int N=4e5+5;
struct eg{int v,nx;}e[N<<1];int head[N],tot;
inline void add(R int u,R int v){e[++tot]={v,head[u]},head[u]=tot;}
struct node{
int mx,mn;
node(){}
node(R int mx,R int mn):mx(mx),mn(mn){}
inline node operator +(const node &b){return node(mx+max(0ll,mn+b.mx),b.mn+min(0ll,mn+b.mx));}
}tr[N<<5];
int w[N],rt[N],ans[N],ls[N<<5],rs[N<<5];
int n,cnt,fa;
void ins(int &p,int l,int r,node x){
if(!p)p=++cnt;if(l==r)return (void)(tr[p]=tr[p]+x);
int mid=(l+r)>>1;
x.mx<=mid?ins(ls[p],l,mid,x):ins(rs[p],mid+1,r,x);
tr[p]=tr[ls[p]]+tr[rs[p]];
}
int merge(int x,int y,int l,int r){
if(!x||!y)return x|y;if(l==r)return tr[x]=tr[x]+tr[y],x;
int mid=(l+r)>>1;
ls[x]=merge(ls[x],ls[y],l,mid),rs[x]=merge(rs[x],rs[y],mid+1,r);
tr[x]=tr[ls[x]]+tr[rs[x]];
return x;
}
void update(int &p,int l,int r,node &x,bool &flag){
if(!p||flag)return;
if(l==r){
if(x.mx+x.mn<0&&x.mx<l)return (void)(flag=1);
x=x+tr[p],p=0;return;
}
int mid=(l+r)>>1;
update(ls[p],l,mid,x,flag),update(rs[p],mid+1,r,x,flag);
if(ls[p]||rs[p])tr[p]=tr[ls[p]]+tr[rs[p]];
else p=0;
}
void dfs(int u){
node res=node(0,-w[u]);
go(u){
res.mx+=w[v],dfs(v);
rt[u]=merge(rt[u],rt[v],0,loli);
}
node qaq=res;bool flag=0;
qaq.mx+=w[u],ans[u]=(qaq+tr[rt[u]]).mx;
update(rt[u],0,loli,res,flag),ins(rt[u],0,loli,res);
}
signed main(){
// freopen("testdata.in","r",stdin);
read(),n=read();
fp(i,2,n)fa=read(),add(fa,i);
fp(i,1,n)w[i]=read();
dfs(1);
fp(i,1,n)print(ans[i]);
return Ot(),0;
}
uoj#418. 【集训队作业2018】三角形(线段树合并)的更多相关文章
- uoj #450[集训队作业2018]复读机
传送门 \(d=1\),那么任何时刻都可以\(k\)个复读机的一种,答案为\(k^n\) \(d>1\),可以枚举某个复读机的复读次数(必须是\(d\)的倍数),然后第\(i\)个复读时间为\( ...
- UOJ 422 [集训队作业2018] 小Z的礼物 min-max容斥 期望 轮廓线dp
LINK:小Z的礼物 太精髓了 我重学了一遍min-max容斥 重写了一遍按位或才写这道题的. 还是期望多少时间可以全部集齐. 相当于求出 \(E(max(S))\)表示最后一个出现的期望时间. 根据 ...
- UOJ#418. 【集训队作业2018】三角形
#418. [集训队作业2018]三角形 和三角形没有关系 只要知道儿子放置的顺序,就可以直接模拟了 记录历史最大值 用一个pair(a,b):之后加上a个,期间最大值为增加b个 合并? A1+A2= ...
- UOJ #449. 【集训队作业2018】喂鸽子
UOJ #449. [集训队作业2018]喂鸽子 小Z是养鸽子的人.一天,小Z给鸽子们喂玉米吃.一共有n只鸽子,小Z每秒会等概率选择一只鸽子并给他一粒玉米.一只鸽子饱了当且仅当它吃了的玉米粒数量\(≥ ...
- 【UOJ#450】【集训队作业2018】复读机(生成函数,单位根反演)
[UOJ#450][集训队作业2018]复读机(生成函数,单位根反演) 题面 UOJ 题解 似乎是\(\mbox{Anson}\)爷的题. \(d=1\)的时候,随便怎么都行,答案就是\(k^n\). ...
- 【UOJ#422】【集训队作业2018】小Z的礼物(min-max容斥,轮廓线dp)
[UOJ#422][集训队作业2018]小Z的礼物(min-max容斥,轮廓线dp) 题面 UOJ 题解 毒瘤xzy,怎么能搬这种题当做WC模拟题QwQ 一开始开错题了,根本就不会做. 后来发现是每次 ...
- [集训队作业2018]蜀道难——TopTree+贪心+树链剖分+链分治+树形DP
题目链接: [集训队作业2018]蜀道难 题目大意:给出一棵$n$个节点的树,要求给每个点赋一个$1\sim n$之内的权值使所有点的权值是$1\sim n$的一个排列,定义一条边的权值为两端点权值差 ...
- UOJ418. 【集训队作业2018】三角形
http://uoj.ac/problem/418 题解 考虑激活每个节点时,它的每个儿子都是放满的. 那每一次的操作我们可以用一个二元组来表示\((w_i-\sum w_{son},\sum w_{ ...
- UOJ#428. 【集训队作业2018】普通的计数题
#428. [集训队作业2018]普通的计数题 模型转化好题 所以变成统计有标号合法的树的个数. 合法限制: 1.根标号比子树都大 2.如果儿子全是叶子,数量B中有 3.如果存在一个儿子不是叶子,数量 ...
随机推荐
- wcf系列(一)--- 寄宿方式
一.自我寄宿(self-hosting) 1.wcf采用基于终结点(Endpoint)的通信手段:终结点由:地址(Address)+绑定(Binding)+契约(Contract)组成: Enpoi ...
- cocos2d-js v3新特性
1.游戏对象 使用cc.game单例代替了原有的cc.Application以及cc.AppControl 2.属性风格API 旧的API ...
- ABAP- INCLUDE Zxxx IF FOUND.
大顾代码: INCLUDE zinc_ca_0002 IF FOUND. - 这肯定是大顾问写出来的 - 一般都不会加东西啊 -加了 IF FOUND 不知道啥意思. 古道无仙(173120830) ...
- codeforces C. Cows and Sequence 解题报告
题目链接:http://codeforces.com/problemset/problem/284/C 题目意思:给出3种操作:t = 1:在前 a 个数中每个数都加上x: t= 2:在数组末尾增加一 ...
- 【转载】Android进程保活招式大全
原文地址:http://dev.qq.com/topic/57ac4a0ea374c75371c08ce8 目前市面上的应用,貌似除了微信和手Q都会比较担心被用户或者系统(厂商)杀死问题.本文对 An ...
- nyoj 1030 hihocoder 1338
题目链接1: 点这里打开. 题目链接2: 点击打开链接 思路:dp,dp[i][j] 表示某个人在区间 i,j上的得分. sum数组表示前 n 项和, num 数组用来存输入的数字. 因为取数字是 ...
- linguistic相关
Knowing a word means knowing both its sound and its meaning, while being able to use a word requires ...
- java推荐书籍及下载
前言 一直有这么个想法,列一下我个人认为在学习和使用Java过程中可以推荐一读的书籍,给初学者或者想深入的朋友一些建议,帮助成长.推荐的的都是我自己读过,也会推荐一些朋友读过并且口碑不错的书籍.以下的 ...
- all.css
@charset "utf-8"*{-webkit-tap-highlight-color:rgba(0,0,0,0); padding:0; margin:0;}body{ fo ...
- POJ 2970 The lazy programmer(贪心+单调优先队列)
A new web-design studio, called SMART (Simply Masters of ART), employs two people. The first one is ...