題意:
有一棵棵提公尺樹,滿足這樣的性質:
每個點上長了一定數量的temmie 薄片,薄片數量記為這個點的權值,這些點被標記為 1 到 n 的整數,其
中 1 號點是樹的根,沒有孩子的點是樹上的葉子。
定義\((a,b)\)是一對相鄰的葉子,當且僅當沒有其它的葉子節點在 dfs 序上在a,b 之間。
每對相鄰的葉子都會產生乙個代價,代價為 a 到 b 路徑上(不包含 a,b)的點中,最大點權值。
提公尺樹可以提供決心,一棵提公尺樹能提供的決心的數量是樹上所有葉子上長的 temmie 薄片數量和,減去所有相鄰葉子的代價。
temmie 們決定對這棵樹進行若干次剪枝(可以不剪枝),使得這棵樹能提供的決心最多。
一次剪枝定義為:如果乙個點的孩子都是葉子,就可以把它所有的孩子剪掉。
要求\(o(n)\)做法。
首先,考慮\(o(n^2)\)的60分暴力:
我們可以反過來:由根開始,每個節點考慮是否擴充套件出所有葉子。
若不擴充套件,則它的子樹都是空的,它成為葉子。
我們可以在dfs序上dp:設\(dp(i,j)\)表示考慮到i,上乙個葉子點為j的最大決心。
有兩種轉移:
1、若i不是葉子,可以擴充套件,轉移到\(dp(i+1,j)\)。
2、可以不擴充套件,轉移到\(dp(i+si_i,i)+w_i-max(i,j)\)。
**如下:
for(int i=tm-1;i>=0;i--)
}printf("%d",dp[0][0]);
考慮優化:首先,要把維度降下來。
設\(dp(i)\)表示i成為葉子後的最大決心。
列舉下乙個使用2轉移的位置,**如下:
for(int i=tm;i>=0;i--)
dp[i]+=sz[u];
}printf("%d",dp[0]);
繼續優化:
我們發現,對於\(i\),\(i+si_i\)就是i的祖先節點中第乙個有更右子節點的點。
而由於注釋處的break,使得轉移就是在\(i+si[u]\)處,一直向左走形成的鏈。
那麼:
綠點對橙點有貢獻。
那麼,我們列舉紅點lca,再列舉相鄰的兩個兒子,計算貢獻。
先算出鏈上每個節點到lca的最大值。設為\(h\),那麼,就是\(dp(u)=max(dp(v)-max(h(u),h(v)))+w(u)\)。
由於h具有單調性,因此分\(h(u)>h(v)\)和\(h(u)<=h(v)\)進行討論,提前算出鏈上\(dp\),以及\(dp-h\)的最大值。
這兩種情況符合的v一定是字首/字尾,雙指標掃一下即可定位。
**細節非常多。
#include #include #define inf 999999999
using namespace std;
vectorve[100010];
int sz[100010],cl[100010],cr[100010],dp[100010],zd[100010],fa[100010],ma[100010],md[100010];
int max(int a,int b)
void dfs0(int u,int f)
t=ve[u][i+1];
while(t!=0)
t=la;while(t!=u)
t=ve[u][i+1];
while(t!=0)
ma[u]=md[u]=-inf;
int x=ve[u][i],y=ve[u][i+1];
while(x!=0)
t=md[(y==0?la:fa[y])]-zd[fa[x]]+sz[x];
if(t>dp[x])dp[x]=t;x=cr[x];
} }if(ve[u].size())dfs1(cl[u]);
}int main()
dp[i]=-inf;
} int u=1;
while(u!=0)
dfs0(1,0);dfs1(1);
int ma=-inf;u=1;
while(u!=0)
printf("%d",ma);
return 0;
}
11 28模擬賽D題解
乙個奇妙的不等式操作 a x a y geq a x xor a y f x f y 所以只有 a x a y geq f x f y 的點才能貢獻答案。這個東西的意義是 a x geq 在 x 子樹且不包含 x y 子樹的點 考場上猜了符合這個條件的點對只有 n log 2 max a i 結果真...
模擬賽 circle 題解
題意 有n個數,問有多少個x,x leq t 滿足這n個數分別 x後,異或和為s。每個數小於 2 m 數字dp。由於是加法,需要記錄進製,因此從低位到高位dp。只要記錄下有幾個進製,就可以根據這n的數的大小知道究竟是哪幾個進製了。設 dp i,j,0 1 表示考慮到第i位,有j個進製,與t的大小關係...
模擬賽2 題解
這次模擬賽最後一道是提答題,就不寫題解了。orz這題 emmm,我無話可說。小範圍記憶化,大範圍遞迴求解 複雜度 o k sqrt 記 f i,j 表示前 j 個數中不被 a i,a dots,a n 整除的個數,答案即為 f 1,n 狀態轉移方程為 f i,j f i 1,j f i 1,j a ...