鏈結
題目描述
有乙個樹狀的城市網路(即 n 個城市由 n-1 條道路連線的連通圖),首都為 1 號城市,每個城市售賣價值為 a_i 的珠寶。
你是乙個珠寶商,現在安排有 q 次行程,每次行程為從 u 號城市前往 v 號城市(走最短路徑),保證 v 在 u 前往首都的最短路徑上。 在每次行程開始時,你手上有價值為 c 的珠寶(每次行程可能不同),並且每經過乙個城市時(包括 u 和 v ),假如那個城市中售賣的珠寶比你現在手上的每一種珠寶都要優秀(價值更高,即嚴格大於),那麼你就會選擇購入。
現在你想要對每一次行程,求出會進行多少次購買事件。
輸入描述:
第一行,兩個正整數 n , q (2 ≤ n ≤ 10^5 , 1 ≤ q ≤ 10^5)。
第二行,n 個正整數 a_i (1 ≤ a_i ≤ 10^5) 描述每個城市售賣的珠寶的價值。
接下來 n-1 行,每行描述一條道路 x , y (1 ≤ x,y ≤ n),表示有一條連線 x 和 y 的道路。
接下來 q 行,每行描述一次行程 u , v , c (1 ≤ u,v ≤ n , 1 ≤ c ≤ 10^5)。
輸出描述:
對於每次行程輸出一行,為所購買次數。
示例1輸入
5 43 5 1 2 4
1 21 3
2 43 5
4 2 1
4 2 2
4 2 3
5 1 5輸出2
110思路 :
考慮用f[i][j]表示從i往上走,能買珠寶的第 2^j個點是哪個,顯然,如果我們知道每個 f[i][0]的值, 那麼f[i][j]=f[f[i][j−1]][j−1] ( i 往上的第2 ^j−1 個點再往上 2^j−1個點)。那麼 f[i][0]怎麼求呢?肯定不能暴力,因為暴力最壞情況可能會讓你每次都跑到根(構造一條鏈,從根到葉子價值遞增)。這個其實也可也倍增著跳——如果 i 的父親fa比i 大那自不必說,當i的父親fa比i 小,那麼我們可以看fa的父親向上走 2^k(k從大到小列舉)個能買進的點的權值(即 f[fa][k]),如果這個點許可權比 i 點權值小,說明還需要往上走,就跳到f[fa] [k]上並把跳躍的長度減少一半(如果還是剛剛的跳躍高度,從f[fa] [k]往上跳 2 ^k
長度,實際上就是從fa跳 2^k+1 ,相當於就是跳到 f[fa][k+1]了);如果 f[fa][k]這個點的權值比 i 大,說明跳多了,就只是把跳躍長度減少一半再看。
注意我這裡說的跳躍長度都是按照能買東西的點的個數計數,相當於我的f陣列其實是對原樹進行了重建,每個點往上走1步都的連向的它能到的第乙個比他大的點(這樣理解也許會容易很多——即我們對原樹進行變形,每個點都連向它上方第乙個能買東西的點,構成乙個新的森林,於是問題就變成了,從u走到自己上方深度不小於dep[v]的點需要經過多少個點)。
有了這個值之後我們要求從 u 往上走到 v 經過了多少點,也可也倍增去求了——即從 u 出發嘗試往上跳 2^k高度,如果已經跳過 v 了,就減小 k,如果沒有跳到 v 的上方,就先跳上去再減小 k。 注意,因為f陣列存的能買東西的點,很有可能v根本不在這裡面,所有跳的時候是通過判斷深度來判斷是否結束的。
這道題孩子想了好久好久 最終還是參考清楚姐姐的思路才想明白 /(ㄒoㄒ)/~~
** :
#include
using
namespace std ;
const
int maxn =
2e5+10;
typedef
long
long ll ;
vector<
int> v[maxn]
;int a[maxn]
, f[maxn][20
], dep[maxn]
, to[maxn]
;void
dfs(
int p ,
int fa)
}int n , q ;
intmain()
for(
int i = n +
1; i <= n + q ; i++
)dfs(1
,0);
for(
int i =
1; i <= q ; i++)}
cout << ans << endl ;
}return0;
}
牛客網 NC207427 直線 高精度
2.解讀 3.time limit c c 1秒,其他語言2秒 memory limit c c 262144k,其他語言524288k 平面上存在 n nn 條直線。請問 n nn 條直線在平面上最多存在多少交點。輸入資料的第一行是t,表示資料的組數 t 100 t 100 t 10 0 接下來每...
城市漫遊 牛客
題解 u v這條簡單路徑上的邊會經過奇數次,其餘的邊會經過偶數次,因為從簡單路徑中的點出去後還得回來。直接算的話每次詢問都得搜整棵樹,顯然效率是極其低的。如果先預處理出整棵樹的邊都經過偶數次的花費v,那麼答案就等於 v 簡單路徑中的邊經過偶數次的花費 簡單路徑中的邊經過奇數次的代價。下一步是得到後兩...
牛客NC18200烟花
總時間限制 1000ms 記憶體限制 262144k 小a有n個烟花,每個烟花代表著互不相同的顏色,對於第i個烟花,它有pi的概率點燃,現在小a要去點燃它們,他想知道產生顏色的期望個數及產生恰好產生k種顏色的概率 第一行兩個整數n,k.接下來一行n個數,第i個數pi表示第i個烟花被點燃的概率 輸出有...