題目傳送門。
首先將 \(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,都種有一棵樹。由於馬路上有一些區域要用來建地鐵。這些區域用它們在數軸上的起始點和終止點表示。已知任一區域的起始點和終止...