BZOJ3999: [TJOI2015]旅游

BZOJ3999: [TJOI2015]旅游

Description

为了提高智商,ZJY准备去往一个新世界去旅游。这个世界的城市布局像一棵树。每两座城市之间只有一条路径可
以互达。每座城市都有一种宝石,有一定的价格。ZJY为了赚取最高利益,她会选择从A城市买入再转手卖到B城市
。由于ZJY买宝石时经常卖萌,因而凡是ZJY路过的城市,这座城市的宝石价格会上涨。让我们来算算ZJY旅游完之
后能够赚取的最大利润。(如a城市宝石价格为v,则ZJY出售价格也为v)

Input

第一行输入一个正整数N,表示城市个数。
接下来一行输入N个正整数表示每座城市宝石的最初价格p,每个宝石的初始价格不超过100。
第三行开始连续输入N-1行,每行有两个数字x和y。表示x城市和y城市有一条路径。城市编号从1开始。
下一行输入一个整数Q,表示询问次数。
接下来Q行,每行输入三个正整数a,b,v,表示ZJY从a旅游到b,城市宝石上涨v。
1≤ N≤50000, 1≤Q ≤50000

Output

 对于每次询问,输出ZJY可能获得的最大利润,如果亏本则输出0。

Sample Input

3
1 2 3
1 2
2 3
2
1 2 100
1 3 100

Sample Output

1
1

题解Here!
额,相信大部分人肯定没有一遍读懂题意。。。
本蒟蒻也是看别的巨佬的博客弄懂的。。。
出题人语文水平真差。。。
其实就是求从$x$到$y$的有向路径上任意两个点的最大差值。

如果这只是一道线段树题还是十分简单的:
对于一个区间,其路径最大差值为:

$$\max \left( \text{右儿子最大差值,左儿子最大差值,(右儿子MAX-左儿子MIN)或者(左儿子MAX-右儿子MIN)} \right)$$

对于这样的要返回多权值的问题,线段树传递结构体比较容易。
这是链上的情况。
然后我们要求的是树的情况。
辣就用树链剖分在$O(\log_2n)$的时间内转换成链上的情况就好了嘛。。。
注意到要解决好一个方向怎么把控的问题。
因为我们在树剖一步一步一步往上爬的时候,从询问起点往上爬和询问终点往上爬是不一样的
我的处理方式是每次都进行判断是线段树左到右还是右到左扫最大差值,之后将每段区间内的$\min$和$\max$记录下来
即:分别开两个数组从起点爬的和终点爬的。
之后再将这一大段区间的$\min$和$\max$连接成一条链,直接暴力跑一次区间最大差值,得到最大答案就是了。
说得容易真的写得很恶心啊!!!

附上将近$200$行的代码:

#include<iostream>
#include<algorithm>
#include<cstdio>
#define LSON rt<<1
#define RSON rt<<1|1
#define MAXSUM(x) b[x].maxn
#define MINSUM(x) b[x].minn
#define MAXL(x) b[x].maxl
#define MAXR(x) b[x].maxr
#define SIGN(x) b[x].c
#define LSIDE(x) b[x].l
#define RSIDE(x) b[x].r
#define WIDTH(x) (RSIDE(x)-LSIDE(x)+1)
#define MAXN 50010
#define MAX (1LL<<62)
using namespace std;
int n,m,c=1,d=1;
int val[MAXN],head[MAXN],deep[MAXN],son[MAXN],size[MAXN],fa[MAXN],id[MAXN],pos[MAXN],top[MAXN];
long long min_x[MAXN],max_x[MAXN],min_y[MAXN],max_y[MAXN];
struct Tree{int next,to;
}a[MAXN<<1];
struct Segment_Tree{long long maxn,minn,maxl,maxr,c;int l,r;
}b[MAXN<<2];
inline int read(){int date=0,w=1;char c=0;while(c<'0'||c>'9'){if(c=='-')w=-1;c=getchar();}while(c>='0'&&c<='9'){date=date*10+c-'0';c=getchar();}return date*w;
}
inline long long max(const long long x,const long long y){return x>y?x:y;}
inline long long min(const long long x,const long long y){return x<y?x:y;}
inline void add(int x,int y){a[c].to=y;a[c].next=head[x];head[x]=c++;a[c].to=x;a[c].next=head[y];head[y]=c++;
}
void dfs1(int rt){son[rt]=0;size[rt]=1;for(int i=head[rt];i;i=a[i].next){int will=a[i].to;if(!deep[will]){deep[will]=deep[rt]+1;fa[will]=rt;dfs1(will);size[rt]+=size[will];if(size[son[rt]]<size[will])son[rt]=will;}}
}
void dfs2(int rt,int f){id[rt]=d++;pos[id[rt]]=rt;top[rt]=f;if(son[rt])dfs2(son[rt],f);for(int i=head[rt];i;i=a[i].next){int will=a[i].to;if(will!=fa[rt]&&will!=son[rt])dfs2(will,will);}
}
inline void pushup(int rt){MAXSUM(rt)=max(MAXSUM(LSON),MAXSUM(RSON));MINSUM(rt)=min(MINSUM(LSON),MINSUM(RSON));MAXL(rt)=max(MAXSUM(RSON)-MINSUM(LSON),max(MAXL(LSON),MAXL(RSON)));MAXR(rt)=max(MAXSUM(LSON)-MINSUM(RSON),max(MAXR(LSON),MAXR(RSON)));
}
inline void pushdown(int rt){if(!SIGN(rt)||LSIDE(rt)==RSIDE(rt))return;SIGN(LSON)+=SIGN(rt);MAXSUM(LSON)+=SIGN(rt);MINSUM(LSON)+=SIGN(rt);SIGN(RSON)+=SIGN(rt);MAXSUM(RSON)+=SIGN(rt);MINSUM(RSON)+=SIGN(rt);SIGN(rt)=0;
}
void buildtree(int l,int r,int rt){LSIDE(rt)=l;RSIDE(rt)=r;SIGN(rt)=0;if(l==r){MAXSUM(rt)=MINSUM(rt)=val[pos[l]];MAXL(rt)=MAXR(rt)=0;return;}int mid=l+r>>1;buildtree(l,mid,LSON);buildtree(mid+1,r,RSON);pushup(rt);
}
void update(int l,int r,long long c,int rt){if(l<=LSIDE(rt)&&RSIDE(rt)<=r){SIGN(rt)+=c;MAXSUM(rt)+=c;MINSUM(rt)+=c;return;}pushdown(rt);int mid=LSIDE(rt)+RSIDE(rt)>>1;if(l<=mid)update(l,r,c,LSON);if(mid<r)update(l,r,c,RSON);pushup(rt);
}
Segment_Tree query(int l,int r,int c,int rt){if(l<=LSIDE(rt)&&RSIDE(rt)<=r)return b[rt];pushdown(rt);int mid=LSIDE(rt)+RSIDE(rt)>>1;if(r<=mid)return query(l,r,c,LSON);if(mid<l)return query(l,r,c,RSON);Segment_Tree ans,lson,rson;lson=query(l,r,c,LSON);rson=query(l,r,c,RSON);ans.maxn=max(lson.maxn,rson.maxn);ans.minn=min(lson.minn,rson.minn);if(c==1)ans.maxr=max(lson.maxn-rson.minn,max(lson.maxr,rson.maxr));elseans.maxl=max(rson.maxn-lson.minn,max(lson.maxl,rson.maxl));return ans;
}
void update_path(int x,int y,long long k){while(top[x]!=top[y]){if(deep[top[x]]<deep[top[y]])swap(x,y);update(id[top[x]],id[x],k,1);x=fa[top[x]];}if(deep[x]>deep[y])swap(x,y);update(id[x],id[y],k,1);
}
void solve(int x,int y){int top_x=0,top_y=0;long long ans=0;Segment_Tree s;while(top[x]!=top[y]){if(deep[top[x]]>deep[top[y]]){s=query(id[top[x]],id[x],1,1);ans=max(ans,s.maxr);top_x++;min_x[top_x]=s.minn;max_x[top_x]=s.maxn;x=fa[top[x]];}else{s=query(id[top[y]],id[y],2,1);ans=max(ans,s.maxl);top_y++;min_y[top_y]=s.minn;max_y[top_y]=s.maxn;y=fa[top[y]];}}if(deep[x]>deep[y]){s=query(id[y],id[x],1,1);ans=max(ans,s.maxr);top_x++;min_x[top_x]=s.minn;max_x[top_x]=s.maxn;}else{s=query(id[x],id[y],2,1);ans=max(ans,s.maxl);top_y++;min_y[top_y]=s.minn;max_y[top_y]=s.maxn;}for(int i=top_y;i>=1;i--){top_x++;min_x[top_x]=min_y[i];max_x[top_x]=max_y[i];}long long maxn=-MAX,minn=MAX;for(int i=1;i<=top_x;i++){ans=max(ans,max_x[i]-minn);minn=min(minn,min_x[i]);}for(int i=top_x;i>=1;i--){ans=max(ans,maxn-min_x[i]);maxn=max(maxn,max_x[i]);}if(ans<0)printf("0\n");else printf("%lld\n",ans);
}
void work(){int x,y,k;while(m--){x=read();y=read();k=read();solve(x,y);update_path(x,y,k);}
}
void init(){int x,y;n=read();for(int i=1;i<=n;i++)val[i]=read();for(int i=1;i<n;i++){x=read();y=read();add(x,y);}m=read();deep[1]=1;dfs1(1);dfs2(1,1);buildtree(1,n,1);
}
int main(){init();work();return 0;
}

 

转载于:https://www.cnblogs.com/Yangrui-Blog/p/9562845.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/397045.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一张图看懂单机/集群/热备/磁盘阵列(RAID)

单机部署(Standalone) 只有一个饮水机提供服务器&#xff0c;服务只部署一份 集群部署(Cluster) 多个饮水机同时提供服务&#xff0c;服务冗余部署&#xff0c;每个冗余的服务都对外提供服务&#xff0c;一个服务挂掉时依然可用 热备部署(Hot-swap) 只有一个桶提供服务&#xf…

typescript vuex_Vue3+TypeScript完整项目上手教程

作者&#xff1a;TinssonTaihttps://juejin.im/post/6875713523968802829一个完整的Vue3Ts项目,支持.vue和.tsx写法 项目地址&#xff1a;https://github.com/vincentzyc/vue3-demo.gitTypeScript 是JS的一个超集&#xff0c;主要提供了类型系统和对ES6的支持&#xff0c;使用 …

JS中window.showModalDialog()详解

window.showModalDialog()方法用来创建一个显示HTML内容的模态对话框。 window.showModelessDialog()方法用来创建一个显示HTML内容的非模态对话框。 使用方法&#xff1a; vReturnValue window.showModalDialog(sURL [, vArguments] [,sFeatures]) vReturnValue window.show…

一个简单的javascript节流器实现

节流器 javascript的节流器主要用于延缓某些动作的执行&#xff0c;比如ajax请求&#xff0c;如果input框注册了input事件&#xff0c;那么当用户输入时就会持续的触发这个事件&#xff0c;如果回调函数中持续的通过ajax调用后台的接口&#xff0c;就会对服务器产生一定压力。这…

一些会用到的知识

为什么80%的码农都做不了架构师&#xff1f;>>> HtmlAgilityPack 用来解析HTML代码 microsoft.mshtml CsQuery 解析HTML代码 转载于:https://my.oschina.net/uwith/blog/813725

eclipse怎么升级到java ee,如何为Java EE开发人员升级Eclipse?

Is there any non-painful way to upgrade an Eclipse installation? I have tried browsing the eclipse site but I cannot find an useful description.解决方案Add the update URL to your available sites:Window > Preferences > Install/Update > Available S…

LeetCode 7 Reverse Integer(反转数字)

题目来源&#xff1a;https://leetcode.com/problems/reverse-integer/ Reverse digits of an integer. Example1: x 123, return 321Example2: x -123, return -321 解题思路&#xff1a; 其实这道题看起来非常简单&#xff0c;要实现也是几行代码的事。但是有个小问题容易被…

各种蕴含算法思想的DP - 3

内容中包含 base64string 图片造成字符过多&#xff0c;拒绝显示转载于:https://www.cnblogs.com/cmyg/p/9566723.html

python图像对比_用python实现对比两张图片的不同

from PIL import Image from PIL import ImageChops def compare_images(path_one, path_two, diff_save_location): """ 比较图片&#xff0c;如果有不同则生成展示不同的图片 参数一: path_one: 第一张图片的路径 参数二: path_two: 第二张图片的路径 参数三:…

Kafka 分布式环境搭建

这篇文章将介绍如何搭建kafka环境&#xff0c;我们会从单机版开始&#xff0c;然后逐渐往分布式扩展。单机版的搭建官网上就有&#xff0c;比较容易实现&#xff0c;这里我就简单介绍下即可&#xff0c;而分布式的搭建官网却没有描述&#xff0c;我们最终的目的还是用分布式来解…

Docker Machine搭建并加入节点

对于集群服务器来讲&#xff0c;要在每台机器上手动安装Docker是一件及其痛苦的事情&#xff0c;还好有Docker Machine这一工具&#xff0c;Docker三剑客中的一角. 一、Docker Machine介绍 这个工具已经出了比较久了&#xff0c;Docker Machine官方介绍&#xff1a;https://doc…

ASPNET5的依赖注入

ASP.NET5设计的时候就是以DI为基础的&#xff0c;它可以利用内建的框架在Startup类的方法中&#xff0c;把依赖注入进去。应用服务也可以被配置的注入。默认的服务容器提供一些基本的功能&#xff0c;它并不打算代替现代主流的DI框架。 1. 什么是Dependency Injection? DI的概…

java 权限控制 demo_Java-访问控制权限

Java面向对象-访问控制权限Java中&#xff0c;可以通过一些Java关键字&#xff0c;来设置访问控制权限&#xff1b;主要有 private(私有)&#xff0c; package(包访问权限)&#xff0c;protected(子类访问权限)&#xff0c;public(公共访问权限)privatepackageprotectedpublic同…

《未来世界的幸存者》笔记

https://ruanyf.github.io/survivor/ 这两天一直在上下班途中&#xff0c;读阮一峰的这本书 《未来世界的幸存者》。还是有不少感慨的。做一下记录。 未来人类社会的形态&#xff0c;将发生颠覆性的变化。旧的社会结构已经在崩溃了&#xff0c;但社会底层的机会变得更少了&…

python类中没有属性_如何在python语言中在类中删除属性和添加属性

在python语言中的类&#xff0c;可以使用class定义类&#xff0c;调用__init__方法进行初始化&#xff1b;默认传入self&#xff0c;可以在后面在添加几个属性。可以使用setattr()添加属性&#xff0c;也可以使用delattr()删除属性。下面利用几个实例说明这两个方法的用法&…

mysql 数据复制停止工作_linux – Mysql GTID复制停止工作

我在主服务器和从服务器之间设置了mysql gtid复制.有趣的是,我发现复制在几分钟后停止工作,我必须使用stop slave并启动slave来重启mysql复制.谁能告诉我是什么原因导致这个问题&#xff1f;改变奴隶主&#xff1a;mysql> change master to-> master_host master.com,-&…

python学生管理系统gui版好例子网_python图书管理系统gui 相关实例(示例源码)下载 - 好例子网...

开发语言&#xff1a;Python | 大小&#xff1a;19.05M | 发布时间&#xff1a;2019-05-27 | 发布人&#xff1a;李易峰 相关标签&#xff1a; 立即下载 开发语言&#xff1a;Python | 大小&#xff1a;0.21M | 发布时间&#xff1a;2020-08-23 | 发布人&#xff1a;聂嘉辉 相关…

COM组件的运行机制

COM组件的运行机制  构造一个创建COM组件的最小框架结构    IUnknown *pUnkNULL;    IObject *pObjectNULL;    CoInitialize(NULL);    CoCreateInstance(CLSID_Object, CLSCTX_INPROC_SERVER, NULL, IID_IUnknown, (void**)&pUnk);    pUnk->Qu…

申请去国外读博士

必须要做的事情是&#xff1a; 考过GRE和TOEFL 准备推荐信 个人CV 联系导师一般就是发邮件 转载于:https://www.cnblogs.com/zhulinmails/p/5078695.html

动态编译

下面的demo就涵盖了动态编译和运行类的过程 package 动态编译; import java.lang.reflect.Method;import java.net.URL;import java.net.URLClassLoader; import javax.tools.JavaCompiler;import javax.tools.ToolProvider; public class Demo { public static void main(Stri…