設t 為一棵有根樹,我們做如下的定義:
• 設a和b為t 中的兩個不同節點。如果a是b的祖先,那麼稱「a比b不知道
高明到**去了」。
• 設a 和 b 為 t 中的兩個不同節點。如果 a 與 b 在樹上的距離不超過某個給定
常數x,那麼稱「a 與b 談笑風生」。
給定一棵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 31 2
1 32 4
4 52 2
4 12 331
31<=p<=n
1<=k<=n
n<=300000
q<=300000
線段樹以深度為關鍵字維護size的和
x,y的答案 = size[x] * min(deep[x], y) + dfs序在l[x] + 1到r[x]之間且深度在deep[x] + 1到deep[x] + k之間的size和
挺有收穫的一道題···第一次發現主席樹每個節點的表示區間可以與其在第幾棵樹無關。
#include#include#include
#include
#include
#include
#include
#include
#include
using
namespace
std;
intread()
returnx;}
const
int n=3e5+50
;struct
node
tree[n
<<6
];int root[n],totr=0
;int first[n],next[n*2],go[n*2],tot=0
;int cnt=0,que[n],in[n],out[n],deep[n],maxdeep=0
,size[n];
intn,q;
inline
void comb(int a,int
b)inline
void dfs(int u,int
fa)
out[u]=cnt;
}inline
void build(int &now,int l,int r,int deep,int
size)
//------------------------------------
inline void insert(const
int &x, int &y, const
int &l, const
int &r, const
int &pos, const
int &v)
//---------------------------------------
inline long
long query(int k,int l,int r,int x,int
y)int
main()
dfs(
1,0);
for(int i=1;i<=cnt;i++)
//for(int i = 1; i <= n; i++) insert(root[i - 1], root[i], 0, maxdeep, deep[que[i]],size[que[i]]-1);
while(q--)
return0;
}
NOI模擬 談笑風生 主席樹
設 t 為一棵有根樹,我們做如下的定義 給定一棵 n 個節點的有根樹 t 節點的編號為 1 n 根節點為 1 號節點。你需要回答 q 個詢問,詢問給定兩個整數 p 和 k 問有多少個有序三元組 a,b,c 滿足 1.a b 和 c 為 t 中三個不同的點,且 a 為 p 號節點 2.a 和 b 都比...
資料結構 主席樹 COGS 2211 談笑風生
輸入檔案 laugh.in輸出檔案 laugh.out簡單對比 時間限制 3 s 記憶體限制 512 mb 問題描述 設t 為一棵有根樹,我們做如下的定義 設a和b為t 中的兩個不同節點。如果a是b的祖先,那麼稱 a比b不知道高明到 去了 設a 和 b 為 t 中的兩個不同節點。如果 a 與 b 在...
湖南集訓 談笑風生 線段樹合併
給一棵樹 n 個節點,q 次詢問,每次給定 p,k 問有多少三元組 p,b,c 滿足 p,b 均為 c 的父親,p,b 在樹上的距離不超過 k n,q le 10 5 很有意思的一道題。兩種情況討論 最後答案即為兩種情況之和 注意空間限制,需要動態開點。include include define ...