樹DP LCA CQBZOJ2937 避難嚮導

2022-05-20 08:52:08 字數 2184 閱讀 7579

題目描述

「特大新聞,特大新聞!全國爆發了一種極其可怕的病毒,已經開始在各個城市 中傳播開來!全國陷入了巨大的危機!大量居民陷入恐慌,想要逃到其它城市以 避難!經調查顯示,該病毒來自於c 市的a 學校的一次非法的……」 「哎。」你關上電視,嘆了口氣。作為a 學校的校長,你一天前為了保命,獨自 逃離了a 學校,拋棄了全校師生,包括那個曾經幫你計算並拆除道路的工程師。 你良心受到了巨大的譴責,因此決定做出一些補救,回答一些逃難的人提出的詢 問。 已知該國一共有n 個城市,並且1 號城市是首都。(n-1)條雙向的公路連線這些 城市,通過這些公路,任意兩個城市之間存在且僅存在一條路徑。每條公路有一 個長度。如果乙個城市只與一條公路相連,則稱它為邊境城市。 該國**有乙個奇怪的規定:每個城市有乙個封閉係數di,定義di 為離這個城 市最遠的邊境城市到這個城市的距離。市民們認為,乙個城市的安全係數si 和 它的封閉係數有很重要的聯絡。a,b,c 是該國的幸運數字,所以大家公認乙個 城市的安全係數si = (di + a) * b mod c。 市民們一共會提出m 次詢問。每個詢問包含三個資訊,xi,yi 和qi。xi 是詢問 者所在的城市編號。你要為這個詢問者在xi 到yi 的必經之路上找出乙個離xi 最近的避難城市,並且要求這個避難城市的安全係數大於等於qi。如果存在這 樣的城市(包含xi 和yi),則輸出城市編號,否則輸出一行包括乙個數-1。

輸入 第一行五個數:依次是n, m, a, b, c。 接下來n-1 行描述公路的資訊。每行三個數,前兩個數代表這條公路連線的兩個 城市的編號,第三個數表示這條公路的長度。 再接下來m 行,每行描述乙個詢問,包含三個數xi, yi 和qi。

輸出 對於每個詢問,輸出一行包含乙個整數,存在符合要求的城市則輸出城市編號, 不存在則輸出-1。

樣例輸入

copy (如果複製到控制台無換行,可以先貼上到文字編輯器,再複製)

7 6 5 6 20

1 2 4

2 4 2

2 5 3

1 3 5

3 6 6

6 7 7

7 5 15

3 4 5

5 4 2

4 5 2

6 6 10

3 5 19

樣例輸出

分析:

用樹dp預處理出離每個城市最遠的邊境城市,然後以任意乙個城市為根進行lca的預處理,p,mx為倍增陣列,分別表示祖先的編號和到祖先路徑上安全係數最大的點的安全係數。

對於每次詢問,找到x,y,的lca,然後找x到lca路徑上安全係數》q且離x最近的點,否則,找x到lca路徑上安全係數》q且離x最遠的點,每次查詢的時間為o(log(n)),總時間複雜度o(n+mlog(n))。

#include

#include

#include

using

namespace

std;

#define maxn 100000

#define maxlog 18

int log,n,m,l[maxn+10],f[maxn+10][2],ms[maxn+10],t,a,b,c,x,y,qi,g[maxn+10],s[maxn+10],ans,fa[maxn+10],p[maxn+10][maxlog],mx[maxn+10][maxlog];

void read(int &x)

}struct nodeedge[maxn*2+10],*adj[maxn+10],*ecnt=edge;

void addedge(int u,int v,int wt)

void dfs1(int u)

else

if(f[v][0]+p->wt>f[u][1])

f[u][1]=f[v][0]+p->wt;

}}void dfs2(int u,int wt)

void prepare()

for(j=1;j<=log;j++)

for(i=1;i<=n;i++)

}int lca(int x,int y)

int find1(int x,int d,int a)

int find2(int x,int d,int a)

int main()

}

設計繼承樹2

4 通過尋找使用共同行為的子類來找出更多抽象化的機會 我們觀察到這六種動物都有makenoise 和eat 兩種方法的共同部分,而wolf與dog可能有某些共同的行為,在lion tiger cat之間也是如此。5 完成類的繼承層次 因為動物本來就有組織化的層次 界 門 綱 目 科 屬 種 我們可以...

樹帝戰記(2)

續 url 6 炮火,70點 戰略很特別 防守,然後很快反擊,樹帝從下方,麒麟和弓箭手從上方殺出來!本關要點 兩個大炮 樹帝 弓箭手對中間猛射!時間稍微有些緊!裝甲左右各一,注意把道路讓開來!本關有可能要樹帝從下方殺出去。因為敵人可能被阻塞!本關弓箭手轉職!img img 這裡的打法很重要,我暫退,...

模板 線段樹 2

題目描述 如題,已知乙個數列,你需要進行下面三種操作 1.將某區間每乙個數乘上x 2.將某區間每乙個數加上x 3.求出某區間每乙個數的和 輸入格式 第一行包含三個整數n m p,分別表示該數列數字的個數 操作的總個數和模數。第二行包含n個用空格分隔的整數,其中第i個數字表示數列第i項的初始值。接下來...