設 t 為一棵有根樹,我們做如下的定義:
給定一棵 n 個節點的有根樹 t ,節點的編號為 1~n ,根節點為 1 號節點。你需要回答 q 個詢問,詢問給定兩個整數 p 和 k ,問有多少個有序三元組 (a,b,c) 滿足:
1. a、b 和 c 為 t 中三個不同的點,且 a 為 p 號節點;
2. a 和 b 都比 c 不知道高明到**去了;
3. a 和 b 談笑風生。這裡談笑風生中的常數為給定的 k 。
輸入的第一行含有兩個正整數n和q,分別代表有根樹的點數與詢問的個數。
接下來 n-1 行,每行描述一條樹上的邊。每行含有兩個整數 u 和 v ,代表在節點 u 和 v 之間有一條邊。
接下來 q 行,每行描述乙個操作。第 i 行含有兩個整數,分別表示第 i 個詢問的 p 和 k 。
輸出 q 行,每行對應乙個詢問,代表詢問的答案。
5 3
1 2
1 3
2 4
4 5
2 2
4 1
2 33 1 3
下圖是樣例資料:
對於詢問2 2, b可以取1或4
b可以在根節點到a的路徑上,此時c可以是a子樹中的任意節點 ans += min(dep[a], k) * (sze[a] - 1)
b可以是a的子樹節點中且與a的距離小於等於k, 對於每乙個b, c可以是b子樹結點中的任意一點
$$ans += \sum_ sze[b] - 1$$
然後需要加上a子樹結點中與a距離小於等於k的節點的子樹大小之和.
#include#includeview code#include
#include
#include
#include
#include
using
namespace
std;
typedef
long
long
ll;const
int n = 300005
;int
n, q;
#define bug(x) cout<
intre()
struct
nodetr[n
<< 6
];int pool, root[n], sze[n], dep[n], in[n], out
[n], id;
int ecnt, adj[n], go[n << 1], nxt[n << 1
], maxx, pos[n];
inline
void insert(const
int &x, int &y, const
int &l, const
int &r, const
int &pos, const
int &v)
inline ll query(
int pos, const
int &nl, const
int &nr, const
int &l, const
int &r)
inline
void addedge(const
int &u, const
int &v)
inline
void dfs(const
int &u, const
int &f)
out[u] =id;
}inline
void
tree_init()
}int
main()
maxx = -1; dep[0] = -1
; dfs(
1, 0
); tree_init();
//for(int i = 1; i <= n; i++) bug(i),bug(dep[pos[i]]);
for(int i = 1; i <= q; i++)
return0;
}
3653 談笑風生
time limit 20 sec memory limit 512 mb submit 498 solved 185 submit status discuss 設t 為一棵有根樹,我們做如下的定義 設a和b為t 中的兩個不同節點。如果a是b的祖先,那麼稱 a比b不知道 高明到 去了 設a 和 b...
湖南集訓 談笑風生
嘟嘟嘟 這題剛開始猶豫了一會兒,以為 高明 的優先順序大於 談笑風生 不過樣例表明只要兩點間距離不超過 x 兩人就算 談笑風生 接下來看看怎麼回答詢問。首先 a 是固定的,且 a,b 都是 c 的祖先。那就得分類討論 1.b 是 a 的祖先,那麼 c 就是 a 的子樹中的所有點,根據乘法原理,三元組...
資料結構 主席樹 COGS 2211 談笑風生
輸入檔案 laugh.in輸出檔案 laugh.out簡單對比 時間限制 3 s 記憶體限制 512 mb 問題描述 設t 為一棵有根樹,我們做如下的定義 設a和b為t 中的兩個不同節點。如果a是b的祖先,那麼稱 a比b不知道高明到 去了 設a 和 b 為 t 中的兩個不同節點。如果 a 與 b 在...