nowcoder1103B 路徑計數機

2021-09-29 09:35:19 字數 3451 閱讀 5534

傳送門 to nowcoder

題目描述

有一棵 n

nn 個點的樹和兩個整數 p,q

p,qp,

q,求滿足以下條件的四元組 (a,

b,c,

d)(a,b,c,d)

(a,b,c

,d) 的個數:

資料範圍與約定

1 ≤n

,p,q

≤3000

1 \le n, p, q \le 3000

1≤n,p,

q≤30

00,1 ≤u

,v≤n

1 \le u, v \le n

1≤u,v≤

n,保證給出的是一棵合法的樹。

首先我們要解決怎樣判斷兩條路徑是否相交

一般樹上路徑問題都得用 lca

lcalc

a 解決,此題也不例外。

考慮 a,b

a,ba,

b 的 lca

lcalc

a,設為 x

xx,再設 lca

(c,d

)=ylca(c,d)=y

lca(c,

d)=y

。如果 x,y

x,yx,

y 不是祖先-

\text-

-後代關係,兩條路徑一定不交。

否則,假設 x

xx 是 y

yy 的祖先,當且僅當 a

aa(或 b

bb)在 y

yy 的子樹內時,兩條路徑相交。

如圖所示,滿足 a

aa 在 y

yy 的子樹內,於是兩條路徑相交。

這提示我們用 f(x

)f(x)

f(x)

表示 lca

lcalc

a 為 x

xx 的點對中,距離為 p

pp 的數量。形式化地說,

f (x

)=∑⟨

a,b⟩

[lca

(a,b

)=x∧

dis(

a,b)

=p]f(x)=\sum_\big[lca(a,b)=x\wedge dis(a,b)=p\big]

f(x)=⟨

a,b⟩

∑​[l

ca(a

,b)=

x∧di

s(a,

b)=p

] 如此一來,所有 lca

lcalc

a 在 a

aa 到 b

bb 的路徑上的點對都不可以計入答案。與之相對的,x

xx 子樹內的其他點作為 lca

lcalc

a 都是可接受的。這玩意兒可以樹上差分。

y

yy 是 x

xx 的祖先怎麼辦?發現在這樣的情況下 x

xx與其父節點的邊一定會被覆蓋到。那麼我們再處理覆蓋一條邊的就是了!

#include

#include

#include

using

namespace std;

inline

intreadint()

struct edge

edge

(int t,

int n):to

(t),

nxt(n)};

const

int maxn =

3001

;int n, p, q;

edge edge[maxn<<1]

;int head[maxn]

, cntedge;

void

addedge

(int from,

int to)

void

init()

}namespace unionfindset

}int lca[maxn]

[maxn]

, depth[maxn]

;void

tarjan

(int x,

int pre)

for(

int i=

1; i<=n;

++i)

if(unionfindset::fa[i]

) lca[x]

[i]= lca[i]

[x]= unionfindset::

findset

(i);

}int

distance

(int a,

int b)

long

long dfsres[maxn]

;// 按照距離分類,計數

void

dfs(

int x,

int deep,

int pre)

long

long cnt1[maxn]

;// lca為i的

void

dfs(

int x,

int pre)

long

long cnt2[maxn]

, tmp[maxn]

;// dis: q

int father[maxn]

;void

solve()

// 找父親大型公益活動

dfs(i,

0,father[i]);

for(

int j=

0; j<=q;

++j)

tmp[j]

= dfsres[j]

, dfsres[j]=0

;dfs

(father[i],0

,i);

for(

int j=

0; j

++j)

cnt2[i]+=

(tmp[j]

*dfsres[q-j-1]

)<<1;

// cnt2計算,覆蓋i與i父親的邊的點對

}dfs(1

,-1)

;// 樹上差分

long

long ans =0;

for(

int i=

1; i<=n;

++i)

for(

int j=

1; j<=n;

++j)

printf

("%lld\n"

,ans);}

intmain()

nowcoder 矩陣最小路徑和

有乙個矩陣map,它每個格仔有乙個權值。從左上角的格仔開始每次只能向右或者向下走,最後到達右下角的位置,路徑上所有的數字累加起來就是路徑和,返回所有的路徑中最小的路徑和。給定乙個矩陣map及它的行數n和列數m,請返回最小路徑和。保證行列數均小於等於100.測試樣例 1,2,3 1,1,1 2,3 返...

nowcoder 84 B 漂亮的樹

題目鏈結 題目描述 街上有n棵樹,標號為1 n,第i棵樹的高度為ai。定義這n棵樹是漂亮的,當且僅當 1.對於所有的i,ai an i 1 2.對於1 i n 2 不是整除 ai 1 ai 1 比如說 2 3 4 5 5 4 3 2 和 1 2 3 2 1 是漂亮的而 1 3 3 1 和 1 2 3...

Nowcoder9983B 內卷(雙指標)

includeusing namespace std const int maxn 1e5 100 int n,k inta maxn b maxn c maxn d maxn e maxn setst,sa mapmp,ma vector int,pair v intcnt intmain sor...