bzoj 5210(树链刨分下做个dp)
5210: 最大连通子块和
Time Limit: 20 Sec Memory Limit: 128 MB
Submit: 211 Solved: 65
[Submit][Status][Discuss]
Description
Input
Output
Sample Input
3 -2 0 3 -1
1 2
1 3
4 2
2 5
Q 1
M 4 1
Q 1
Q 2
Sample Output
3
1
#include<bits/stdc++.h>
#define clr(x) memset(x,0,sizeof(x))
#define clr_1(x) memset(x,-1,sizeof(x))
#define INF 0x3f3f3f3f
#define LL long long
#define pb push_back
#define ls(i) (i<<1)
#define rs(i) (i<<1|1)
#define mp make_pair
#define fi first
#define se second
using namespace std;
const int N=2e5+;
int tsize[N];
int son[N],down[N],top[N],dep[N],pos[N],pot[N],fat[N];
int tot;
int n,q;
LL v[N],f[N],g[N],maxs[N];
vector<int> e[N];
struct heap
{
priority_queue<LL> ins,del;
inline void push(LL x)
{
ins.push(x);
return ;
}
inline void pop(LL x)
{
del.push(x);
return ;
}
inline LL top()
{
while(!del.empty() && ins.top()==del.top())
ins.pop(),del.pop();
if(ins.empty()) return 0LL;
return ins.top();
}
void pop()
{
top();
del.push(ins.top());
return ;
}
}lsq[N];
void dfs1(int u,int d,int fa)
{
// cout<<"begin:"<<u<<" "<<son[u]<<endl;
dep[u]=d;
tsize[u]=;
fat[u]=fa;
int sz=e[u].size(),p;
for(int i=;i<sz;i++)
{
p=e[u][i];
// cout<<"branch:"<<u<<" "<<p<<" "<<fa<<endl;
if(p!=fa)
{
dfs1(p,d+,u);
tsize[u]+=tsize[p];
if(!son[u] || tsize[p]>tsize[son[u]])
son[u]=p;
}
}
// cout<<"endn:"<<u<<" "<<son[u]<<endl;
return ;
}
void dfs2(int u,int tp)
{
// cout<<u<<endl;
top[u]=tp;
pos[u]=++tot;
pot[tot]=u;
if(son[u]) dfs2(son[u],tp),down[u]=down[son[u]],maxs[u]=maxs[son[u]];
else down[u]=u,maxs[u]=;
int sz=e[u].size();
g[u]=v[u];
for(int i=;i<sz;i++)
{
int p=e[u][i];
if(p!=fat[u] && p!=son[u])
{
dfs2(p,p);
g[u]+=f[p];
lsq[u].push(maxs[p]);
}
}
f[u]=max(0LL,g[u]+f[son[u]]),maxs[u]=max(maxs[u],f[u]),maxs[u]=max(maxs[u],lsq[u].top());
return ;
}
struct segt
{
int l,r;
LL all,maxl,maxr,maxn;
segt operator + (const segt &b)
{
segt p;
p.maxl=max(maxl,all+b.maxl);
p.maxr=max(b.maxr,maxr+b.all);
p.all=all+b.all;
p.maxn=max(max(maxn,b.maxn),maxr+b.maxl);
p.l=l;
p.r=b.r;
return p;
}
}seg[N<<];
void init(int i,int l,int r)
{
if(l==r)
{
int x=pot[l];
seg[i]=(segt){l,r,g[x],max(0LL,g[x]),max(0LL,g[x]),max(g[x],lsq[x].top())};
return ;
}
int mid=l+r>>;
init(i<<,l,mid);
init(i<<|,mid+,r);
seg[i]=seg[i<<]+seg[i<<|];
return ;
}
char s[];
void refresh(int i,int pos)
{
if(seg[i].l==seg[i].r)
{
int x=pot[seg[i].l];
segt p=(segt){seg[i].l,seg[i].r,g[x],max(0LL,g[x]),max(0LL,g[x]),max(g[x],lsq[x].top())};
seg[i]=p;
return ;
}
int mid=seg[i].l+seg[i].r>>;
if(mid>=pos) refresh(i<<,pos);
else refresh(i<<|,pos); seg[i]=seg[i<<]+seg[i<<|];
return ;
}
segt query(int i,int l,int r)
{
if(seg[i].l>=l && seg[i].r<=r) return seg[i];
int mid=seg[i].l+seg[i].r>>;
if(r<=mid) return query(i<<,l,r);
if(l>mid) return query(i<<|,l,r);
return query(i<<,l,r)+query(i<<|,l,r);
}
void update(int u,LL val)
{
segt t1,t2,t3;
bool flag=;
// cout<<u<<endl;
while(u)
{
// cout<<u<<endl;
t3=query(,pos[top[u]],pos[down[u]]);
if(flag) lsq[u].pop(t1.maxn),lsq[u].push(t2.maxn);
t1=t3;
flag=;
g[u]+=val,refresh(,pos[u]);
t2=query(,pos[top[u]],pos[down[u]]);
val=t2.maxl-f[top[u]],f[top[u]]=t2.maxl;
u=fat[top[u]];
}
return ;
}
int main()
{
tot=;
scanf("%d%d",&n,&q);
for(int i=;i<=n;i++)
scanf("%lld",v+i);
for(int i=;i<=n;i++)
{
int u,v;
scanf("%d%d",&u,&v);
e[u].pb(v);
e[v].pb(u);
}
dfs1(,,);
dfs2(,);
init(,,n);
for(int i=;i<=q;i++)
{
scanf("%s",s);
if(s[]=='M')
{
int u;
LL num;
scanf("%d%lld",&u,&num);
update(u,num-v[u]);
v[u]=num;
}
else
{
int u;
scanf("%d",&u);
printf("%lld\n",query(,pos[u],pos[down[u]]).maxn);
}
}
return ;
}
bzoj 5210(树链刨分下做个dp)的更多相关文章
- hdu 5452(树链刨分)
看到题目,想了挺长时间,发现不会,然后看着样子像是树上成段操作,所以查了下树链刨分,结果真的就是这个东西... Minimum Cut Time Limit: 3000/2000 MS (Java/O ...
- xcoj 1103 插线板(树链刨分求最大子段和)
1103: 插线板 时间限制: 1 Sec 内存限制: 128 MB提交: 14 解决: 7 标签提交统计讨论版EditTestData 题目描述 从前有一堆古老的插线板,任意两个插线板之间只有一 ...
- 树链刨分(class版)
class版树链剖(刨)分 感谢沙华大佬的赞助 其实没什么太大变化,就是用了几次一顿乱指... CODE: #include<iostream> #include<cstdio> ...
- HDU - 3966 树链刨分
题目传送门 操作就是询问某个点的值, 然后就是对一条路径上的值全部修改. 最基本的树刨题目了. 树刨的思想: 1. 对于每个点找到他的重儿子. void dfs1(int o, int u){ sz[ ...
- P3565 由简单的树形dp 引入 长链刨分
这道题感觉不太行 因为自己没想出来. 先说一下暴力吧,取三个点 让两两之间的距离相等怎么做呢,看起来是很复杂的样子的,但是仔细观察发现 答案出自一个点的儿子之间 或者儿子和父亲之间. 暴力枚举三个点然 ...
- POJ 2763 Housewife Wind 树链拋分
一.前言 这破题WA了一天,最后重构还是WA,最后通过POJ讨论版得到的数据显示,我看上去是把某个变量写错了..于是,还是低级错误背锅啊....代码能力有待进一步提升2333333 二.题意 某家庭主 ...
- HDU 3966 Aragorn's Story 树链拋分
一.写在前面 终于开始开坑link-cut-tree这个了,对于网上找到的大佬的前进路线,进行了一番研发,发现实际上可以实现对于树链拋分的制作.经历了若干长时间之后终于打了出来(为什么每次学什么东西都 ...
- BZOJ 1036 && 树链剖分
还是太弱啊..各种数据结构只听过名字却没有一点概念..树链剖分也在这个范畴..今天来进一步深化一下教育改革推进全民素质提高. 性质 忘了在哪里看到的一篇blog有一句话讲得非常好,树链剖分不是一种数据 ...
- bzoj 4196 树链剖分 模板
[Noi2015]软件包管理器 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 2135 Solved: 1232[Submit][Status][D ...
随机推荐
- APScheduler API -- apscheduler.triggers.interval
apscheduler.triggers.interval API Trigger alias for add_job(): interval class apscheduler.triggers.i ...
- 查看oracle实例名
select name from v$database; show parameter service_names;
- 关于limit_req和limit_conn的区别
1,首先,limit_req和limit_conn两个模块都是为了来限流的,但是两者不在一个层面,为了搞清楚这个,必须先要弄清楚request和connection的区别,因为在很多情况下,我们把他们 ...
- Robotium测试套管理测试用例
前提:已写好测试用例 新建个测试套MyTestSuite管理你需要跑的测试用例,或者将相同功能的测试用例归纳到一个测试套中 package com.robotium.test.testsuite; i ...
- jQuery UI 给button添加ID
$("#addOrEditApp").dialog({ modal: true ,maxHeight:dialogHeight,width:dialog_width,title: ...
- 08 Packages 包
Packages Standard library Other packages Sub-repositories Community Standard library Name Synopsis ...
- wiki confluence安装
注意:安装前请先确认内存 至少2G 1.上传 atlassian-confluence-5.9.3-x64.bin 文件,修改权限 chmod 777 atlassian-confluence-5.9 ...
- wpf 查找 子元素
RightContainer.ApplyTemplate();//如果找不到,就执行该句试一试 var xxx=UIHelper.FindChild<ScrollViewer>(Right ...
- (三)HtmlUnit 实践
第一节: htmlunit 爬取百度云资源
- JS中给函数参数添加默认值
最近在Codewars上面看到一道很好的题目,要求用JS写一个函数defaultArguments,用来给指定的函数的某些参数添加默认值.举例来说就是: // foo函数有一个参数,名为x var f ...