P7091 數上的樹

2022-06-16 12:30:13 字數 1594 閱讀 4451

題目傳送門。

首先將 \(n\) 分解質因數,用 dfs 求出 \(n\) 的所有因數,記為 \(d_1,d_2,\cdots,d_c\),跑一遍反素數那題的**可知 \(c\leq 23327\)(

設 \(f_i\) 表示根節點為 \(d_i\) 時最小值。

顯然,區域性最優值可以保證整體最優值,且轉移無後效性,即求 \(f_i\) 時不會影響 \(f_j\ (d_j,故答案可以用樹形 dp 求出,將所有因數排序後可以轉化為序列上的 dp。

對於不能出現在樹上的 \(d_i\) 直接 skip 即可。

設 \(g_i\) 表示 \(d_i\) 所含有的質因子個數。for example,\(12=2\times 2\times 3\),所以 \(12\) 有 \(3\) 個質因子。在本題中,\(g_\) 也表示以 \(d_i\) 為根的子樹的節點個數,不難發現其為定值。

假設當前轉移 \(f_i\) 決策點為 \(j,k\ (d_j\times d_k=d_i)\),那麼對於 \(d_j\) 和 \(d_k\) 子樹內兩兩組合出的 pairs 的貢獻可以直接由 \(f_j+f_k\) 推得,剩下來只有兩種情況:

轉移方程:

\[f_i=\min_f_j+f_k+(g_j\times g_k+g_i)\times d_i

\],其中 \(g_i=g_j+g_k+1\) 可以在 dp 時一併求出。

這樣子搞是 \(\mathcal o(c^3)\) 的,顯然無法接受。

綜上,我們有了乙個 \((\sqrt n+m\log c+c^2)\) 的演算法(分解質因數 + 處理限制需要二分查詢 + dp),**如下:

ll n,m,num[n],f[n];

ll cnt,pr[n],c[n],tot;

ll fc[n],il[n],d;

map isp;

void dfs(int pos,ll prod) for(int i=0;i<=c[pos];i++)dfs(pos+1,prod),prod*=pr[pos];

}int main()

if(n>1)pr[++cnt]=n,tot++,c[cnt]=1,isp[n]=1;

n=tmp;

// find factors

dfs(1,1);

sort(fc+1,fc+d+1);

// limit

for(int i=1;i<=m;i++)

// dp

for(int i=1;i<=d;i++) il[i]=1,f[i]=inf; // 如果無法由以前的 j,k 轉移得到那麼 i 也無法得到

int p=i-1;

for(int j=1;jfc[i]/fc[j])p--;

if(j>p)break;

if(!il[j]&&!il[p])f[i]=min(f[i],f[j]+f[p]+num[j]*num[p]*fc[i]+(num[i]=num[j]+num[p]+1)*fc[i]),il[i]=0;

} } if(il[d])puts("-1");

else cout<<(ll)f[d]

}

p1268 樹的重量

傳送門 題目 樹可以用來表示物種之間的進化關係。一棵 進化樹 是乙個帶邊權的樹,其葉節點表示乙個物種,兩個葉節點之間的距離表示兩個物種的差異。現在,乙個重要的問題是,根據物種之間的距離,重構相應的 進化樹 令n 用乙個n上的矩陣m來定義樹t。其中,矩陣m滿足 對於任意的i,j,k,有m i,j m ...

洛谷P5043 樹的同構(樹hash)

這題就是無腦,萌新不知道什麼叫樹的重心,也不知道什麼叫最小表示法排序,萌新只會無腦hash 對每一棵樹,每乙個節點為根跑一次hash值,強行判斷就好 最後用並查集維護一下,其他看 吧 include include include include include include using name...

P1047 校門外的樹

某校大門外長度為l的馬路上有一排樹,每兩棵相鄰的樹之間的間隔都是1公尺。我們可以把馬路看成乙個數軸,馬路的一端在數軸0的位置,另一端在l的位置 數軸上的每個整數點,即0,1,2,l,都種有一棵樹。由於馬路上有一些區域要用來建地鐵。這些區域用它們在數軸上的起始點和終止點表示。已知任一區域的起始點和終止...