有一棵n個點的樹和兩個整數p, q,求滿足以下條件的四元組(a, b, c, d)的個數:
1.$1\leq a,b,c,d \leq n$
2.點a到點b的經過的邊數為p。
3.點c到點d的經過的邊數為q。
4.不存在乙個點,它既在點a到點b的路徑上,又在點c到點d的路徑上。
第一行三個整數n,p,q。
接下來n - 1行,每行兩個整數u, v,表示樹上存在乙個連線點u和點v的邊。
輸出乙個整數,表示答案。
示例1輸入
5 2 1
1 22 3
3 42 5輸出4
說明合法的四元組一共有:
(1, 5, 3, 4),
(1, 5, 4, 3),
(5, 1, 3 ,4),
(5, 1, 4, 3)。
示例2輸入
4 1 1
1 22 3
3 4輸出
8備註:
對於前20%的資料,n,p,q≤50。
對於前40%的資料,n,p,q≤200。
對於另外10%的資料,p = 2, q = 2。
對於另外10%的資料,樹是一條鏈。
對於另外10%的資料,樹隨機生成。
對於所有資料1≤n,p,q≤3000,1≤u,v≤n,保證給出的是一棵合法的樹。
分析我已經弱到連$n^2$列舉路徑都不會了
再一次求助master_yi
這個題只要理順了就挺好想的了(說得好像我想得出來似的。
由於不相交的情況不好求,所直接看相交的情況。
找規律可以發現,如果兩條路徑相交,其中必有一條路徑兩個端點的lca在另一條路徑上
所有可以列舉長度為p的路徑,減去在以這條路徑上的點為端點lca的長度為q的路徑
然後又列舉長度為q的路徑,減去在以這條路徑上的點為端點lca的長度為p的路徑
發現當路徑端點lca相同的情況被多算了一次,於是就加回來
那麼如何實現呢?
設sq[x],sp[x]分別表示以x為端點lca,長度為q和長度為p的路徑條數
列舉路徑是$n^2$的,如果不能優化的話,那麼我們現在需要的是快速求出一條路徑上的sq或sp和
現在要求的是一條路徑的和,乙個乙個找點肯定會t,所以可以預處理一些東西能讓我們能夠拼湊出答案
如果預處理從根到某個節點x上的路徑的sq之和與sp之和,記為ssq[x]與spp[x]
那麼以i,j為兩端點的路徑中sq和sp之和就為ssq[i]+ssq[j]-ssq[lca[i][j]]-ssq[fa[lca[i][j]]]與ssp[i]+ssp[j]-ssp[lca[i][j]]-ssp[fa[lca[i][j]]]
感覺有些與字首和類似。。。。。。
這樣就可以o(1)計算了,總的時間複雜度就為o(n^2)
跟master_yi幾乎一樣的code
#include#includeusing
namespace
std;
const
int maxn=3005
;int
fa[maxn],dep[maxn],ori[maxn],f[maxn][maxn],lca[maxn][maxn];
int n,p,q,ecnt,sp,sq,v[maxn<<1],nx[maxn<<1
],sq[maxn],sp[maxn],vis[maxn],info[maxn];
int find(int x)
void add(int u1,int v1)
void dfs1(int x,int
fa) ori[x]=fa;sq+=sq[x];sp+=sp[x];
}void dfs2(int x,int f)
intmain()
if(len==p)ans-=sq[i]+sq[j]-sq[lca[i][j]]-sq[fa[lca[i][j]]];
if(len==q)ans-=sp[i]+sp[j]-sp[lca[i][j]]-sp[fa[lca[i][j]]];
}for(int i=1;i<=n;i++)
if(p==q)ans+=1ll*(sp[i]-sp[fa[i]])*(sq[i]-sq[fa[i]]-1)/2
;
else ans+=1ll*(sp[i]-sp[fa[i]])*(sq[i]-sq[fa[i]]);
printf(
"%lld\n
",p==q?ans<<3:ans<<2);}
黑白樹(牛客網 樹形dp)
題目描述 一棵n個點的有根樹,1號點為根,相鄰的兩個節點之間的距離為1。樹上每個節點i對應乙個值k i 每個點都有乙個顏色,初始的時候所有點都是白色的。你需要通過一系列操作使得最終每個點變成黑色。每次操作需要選擇乙個節點i,i必須是白色的,然後i到根的鏈上 包括節點i與根 所有與節點i距離小於k i...
牛客訓練,殺樹,樹形dp
一道樹形dp題,我剛開始想的是dp i j dp i j dp i j 表示i為根結點最長鏈的長度為j的最小代價,轉移的時候很複雜,最後還是沒寫出來 也有可能是寫炸了,但是這個狀態應該也是可以的 比賽結束後看到題解是用dp i j dp i j dp i j 表示i為根結點最長鏈的長度小於等於j的最...
牛客網 黑白樹(樹形dp)
一棵n個點的有根樹,1號點為根,相鄰的兩個節點之間的距離為1。樹上每個節點i對應乙個值k i 每個點都有乙個顏色,初始的時候所有點都是白色的。你需要通過一系列操作使得最終每個點變成黑色。每次操作需要選擇乙個節點i,i必須是白色的,然後i到根的鏈上 包括節點i與根 所有與節點i距離小於k i 的點都會...