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.pswp.cn/news/397045.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/397045.shtml
英文地址,請注明出處:http://en.pswp.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…