题目大意

  给你一棵树,有\(n\)个点。有\(q\)个操作,每次要你从\(x\)到\(y\)的路径上选两个点,使得距离\(x\)比较远的点的点权\(-\)距离\(x\)比较近的点的点权最大,然后把这条路径上所有点的点权\(+v\)。

  \(n,q\leq 50000\)

题解

  这种题没什么意思,直接树剖就好了。

  线段树上每个点记录最大值,最小值,从左往右走和从右往左走的最大收益。

  时间复杂度:\(O(n+q\log^2 n)\)

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<ctime>
#include<utility>
#include<cmath>
#include<functional>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
void sort(int &a,int &b)
{
if(a>b)
swap(a,b);
}
void open(const char *s)
{
#ifndef ONLINE_JUDGE
char str[100];
sprintf(str,"%s.in",s);
freopen(str,"r",stdin);
sprintf(str,"%s.out",s);
freopen(str,"w",stdout);
#endif
}
int rd()
{
int s=0,c;
while((c=getchar())<'0'||c>'9');
do
{
s=s*10+c-'0';
}
while((c=getchar())>='0'&&c<='9');
return s;
}
int upmin(int &a,int b)
{
if(b<a)
{
a=b;
return 1;
}
return 0;
}
int upmax(int &a,int b)
{
if(b>a)
{
a=b;
return 1;
}
return 0;
}
struct pp
{
ll ma,mi;
ll s1,s2;
pp()
{
ma=mi=s1=s2=0;
}
};
pp merge(pp a,pp b)
{
pp c;
c.s1=max(b.ma-a.mi,max(a.s1,b.s1));
c.s2=max(a.ma-b.mi,max(a.s2,b.s2));
c.ma=max(a.ma,b.ma);
c.mi=min(a.mi,b.mi);
return c;
}
pp rev(pp a)
{
swap(a.s1,a.s2);
return a;
}
int c[100010];
namespace seg
{
struct tree
{
int ls,rs;
int l,r;
ll t;
pp s;
};
tree a[100010];
int cnt;
void build(int &p,int l,int r)
{
p=++cnt;
a[p].l=l;
a[p].r=r;
if(l==r)
{
a[p].s.ma=a[p].s.mi=c[l];
return;
}
int mid=(l+r)>>1;
build(a[p].ls,l,mid);
build(a[p].rs,mid+1,r);
a[p].s=merge(a[a[p].ls].s,a[a[p].rs].s);
}
void add(int p,ll v)
{
a[p].s.ma+=v;
a[p].s.mi+=v;
a[p].t+=v;
}
void push(int p)
{
if(a[p].t&&a[p].ls!=a[p].r)
{
add(a[p].ls,a[p].t);
add(a[p].rs,a[p].t);
a[p].t=0;
}
}
void add(int p,int l,int r,int v)
{
if(l<=a[p].l&&r>=a[p].r)
{
add(p,v);
return;
}
push(p);
int mid=(a[p].l+a[p].r)>>1;
if(l<=mid)
add(a[p].ls,l,r,v);
if(r>mid)
add(a[p].rs,l,r,v);
a[p].s=merge(a[a[p].ls].s,a[a[p].rs].s);
}
pp query(int p,int l,int r)
{
if(l<=a[p].l&&r>=a[p].r)
return a[p].s;
push(p);
int mid=(a[p].l+a[p].r)>>1;
if(r<=mid)
return query(a[p].ls,l,r);
if(l>mid)
return query(a[p].rs,l,r);
return merge(query(a[p].ls,l,r),query(a[p].rs,l,r));
}
}
struct graph
{
int v[100010];
int t[100010];
int h[50010];
int n;
graph()
{
n=0;
}
void add(int x,int y)
{
n++;
v[n]=y;
t[n]=h[x];
h[x]=n;
}
};
graph g;
struct p
{
int f,w,t,d,ms,s;
};
p a[100010];
int wcnt;
void dfs1(int x,int fa,int dep)
{
a[x].f=fa;
a[x].d=dep;
a[x].s=1;
int ms=0;
int i;
for(i=g.h[x];i;i=g.t[i])
if(g.v[i]!=fa)
{
dfs1(g.v[i],x,dep+1);
if(a[g.v[i]].s>ms)
{
ms=a[g.v[i]].s;
a[x].ms=g.v[i];
}
a[x].s+=a[g.v[i]].s;
}
}
void dfs2(int x,int top)
{
a[x].w=++wcnt;
a[x].t=top;
if(!a[x].ms)
return;
dfs2(a[x].ms,top);
int i;
for(i=g.h[x];i;i=g.t[i])
if(g.v[i]!=a[x].f&&g.v[i]!=a[x].ms)
dfs2(g.v[i],g.v[i]);
}
int prize[100010];
int rt;
ll query(int x,int y,int z)
{
pp s1,s2;
s1.ma=s1.mi=0x7fffffff;
s2.ma=s2.mi=-0x7fffffff;
while(a[x].t!=a[y].t)
if(a[a[x].t].d>a[a[y].t].d)
{
s1=merge(s1,rev(seg::query(rt,a[a[x].t].w,a[x].w)));
seg::add(rt,a[a[x].t].w,a[x].w,z);
x=a[a[x].t].f;
}
else
{
s2=merge(seg::query(rt,a[a[y].t].w,a[y].w),s2);
seg::add(rt,a[a[y].t].w,a[y].w,z);
y=a[a[y].t].f;
}
if(a[x].w<a[y].w)
{
s2=merge(seg::query(rt,a[x].w,a[y].w),s2);
seg::add(rt,a[x].w,a[y].w,z);
}
else
{
s1=merge(s1,rev(seg::query(rt,a[y].w,a[x].w)));
seg::add(rt,a[y].w,a[x].w,z);
}
s1=merge(s1,s2);
return s1.s1;
}
int main()
{
open("bzoj3999");
int n,q;
scanf("%d",&n);
int i,x,y,z;
for(i=1;i<=n;i++)
scanf("%d",&prize[i]);
for(i=1;i<n;i++)
{
scanf("%d%d",&x,&y);
g.add(x,y);
g.add(y,x);
}
dfs1(1,0,1);
dfs2(1,1);
for(i=1;i<=n;i++)
c[a[i].w]=prize[i];
seg::build(rt,1,n);
scanf("%d",&q);
for(i=1;i<=q;i++)
{
scanf("%d%d%d",&x,&y,&z);
ll ans=query(x,y,z);
printf("%lld\n",ans);
}
return 0;
}

【BZOJ3999】【TJOI2015】旅游 树剖的更多相关文章

  1. BZOJ3999:[TJOI2015]旅游(树链剖分)

    Description 为了提高智商,ZJY准备去往一个新世界去旅游.这个世界的城市布局像一棵树.每两座城市之间只有一条路径可 以互达.每座城市都有一种宝石,有一定的价格.ZJY为了赚取最高利益,她会 ...

  2. BZOJ3999 [TJOI2015]旅游 【树剖 + 线段树】

    题目 为了提高智商,ZJY准备去往一个新世界去旅游.这个世界的城市布局像一棵树.每两座城市之间只有一条路径可 以互达.每座城市都有一种宝石,有一定的价格.ZJY为了赚取最高利益,她会选择从A城市买入再 ...

  3. P1505 [国家集训队]旅游[树剖]

    题目描述 Ray 乐忠于旅游,这次他来到了T 城.T 城是一个水上城市,一共有 N 个景点,有些景点之间会用一座桥连接.为了方便游客到达每个景点但又为了节约成本,T 城的任意两个景点之间有且只有一条路 ...

  4. 2019.01.20 bzoj3999: [TJOI2015]旅游(树链剖分)

    传送门 树链剖分菜题. 题意不清差评. 题意简述(保证清晰):给一棵带权的树,每次从aaa走到bbb,在走过的路径上任意找两个点,求后访问的点与先访问的点点权差的最大值. 思路: 考虑暴力:维护路径的 ...

  5. BZOJ3999 [TJOI2015]旅游

    题面:给定一个有$n$个节点的树,每个点又点权$v_i$,每次选取一条树链$[a, b]$,求出$max(v_i - v_j)$,其中$i, j \in [a, b]$且$i$出现在$j$前面,最后树 ...

  6. 【BZOJ3999】[TJOI2015]旅游(Link-Cut Tree)

    [BZOJ3999][TJOI2015]旅游(Link-Cut Tree) 题面 BZOJ 洛谷 题解 一道不难的\(LCT\)题(用树链剖分不是为难自己吗,这种有方向的东西用\(LCT\)不是方便那 ...

  7. BZOJ_2157_旅游_树剖+线段树

    BZOJ_2157_旅游_树剖+线段树 Description Ray 乐忠于旅游,这次他来到了T 城.T 城是一个水上城市,一共有 N 个景点,有些景点之间会用一座桥连接.为了方便游客到达每个景点但 ...

  8. BZOJ2157 旅游 【树剖 或 LCT】

    题目 Ray 乐忠于旅游,这次他来到了T 城.T 城是一个水上城市,一共有 N 个景点,有些景点之间会用一座桥连接.为了方便游客到达每个景点但又为了节约成本,T 城的任意两个景点之间有且只有一条路径. ...

  9. luoguP1505旅游(处理边权的树剖)

    /* luogu1505 非常简单的处理边权的树剖题. 在树上将一条边定向,把这条边的权值赋给这条边的出点 树剖的时候不计算lca权值即可 */ #include<bits/stdc++.h&g ...

随机推荐

  1. H5 类选择器

    10-类选择器 错误的写法: --> 迟到毁一生 早退穷三代 按时上下班 必成高富帅 我是段落 我是段落 <!DOCTYPE html> <html lang="en ...

  2. H5 CSS的格式

    02-CSS的格式 标签名称{ 属性名称: 属性对应的值; ... } 2.注意点: 1.style标签必须写在head标签的开始标签和结束标签之间(也就是必须和title标签是兄弟关系) 2.sty ...

  3. java web 常见异常及解决办法

    javax.servlet.ServletException: javax/servlet/jsp/SkipPageException 重启tomcat, javax.servlet.ServletE ...

  4. Java中有关Null的9件事(转)

    对于Java程序员来说,null是令人头痛的东西.时常会受到空指针异常(NPE)的骚扰.连Java的发明者都承认这是他的一项巨大失误.Java为什么要保留null呢?null出现有一段时间了,并且我认 ...

  5. [转帖]浏览器的F5和Ctrl+F5

    浏览器的F5和Ctrl+F5 https://www.cnblogs.com/xiangcode/p/5369084.html 在浏览器里中,按F5键和按F5同时按住Ctrl键(简称Ctrl+F5), ...

  6. windows浏览器访问虚拟机开的rabbitmq服务,无法访问

    根据这个博主的建议 https://blog.csdn.net/csdnliuxin123524/article/details/78207427 换了一个浏览器上火狐浏览器输入“localhost: ...

  7. php-memcached详解

    一.memcached 简介 在很多场合,我们都会听到 memcached 这个名字,但很多同学只是听过,并没有用过或实际了解过,只知道它是一个很不错的东东.这里简单介绍一下,memcached 是高 ...

  8. Mysql优化单表查询

    借助explain分析SQL,判断该怎么建立索引. 还需要注意,有些情况会导致索引失效,用不上索引,应该优化SQL,应用上索引. 什么情况导致索引失效? 1.在索引列上做任何操作(计算.函数.类型转换 ...

  9. 用junit对java代码进行测试,需要注意

    1.用@Test注解的方法必须没有返回值,返回值类型无:void 2.用@Test注解的方法必须没有参数.

  10. 【转】解决Maxwell发送Kafka消息数据倾斜问题

    最近用Maxwell解析MySQL的Binlog,发送到Kafka进行处理,测试的时候发现一个问题,就是Kafka的Offset严重倾斜,三个partition,其中一个的offset已经快200万了 ...