題目大意:$noip2018\;tg\;d1t3$
題解:題目要求最短的賽道的長度最大,可以想達到二分答案,接著就是乙個顯然的樹形$dp$。
發現對於乙個點,它子樹中若有兩條鏈結起來比要求的答案大,一定接起來成為一條路徑,因為接起來答案一定加一,而傳遞上去的話不一定。然後對於一條鏈,一定是找可行的最短的鏈與它相接,把盡可能長的鏈傳遞上去。找最小的可行的鏈我使用了雙向鍊錶(複雜度$o(n)$,右端點總共最多向左移動$n$次,每次最多向右移動$1$次)
卡點:考場上寫結束後刪除節點後轉移到下乙個節點時,沒有考慮到移動到的節點也被刪除的情況(考場上我是真的傻)
c++ code:
#include #include #include #include namespace r}using r::read;
#define maxn 50010
const int tang_yx = 20040826;
inline int max(int a, int b)
int head[maxn], cnt;
struct edge e[maxn << 1];
inline void add(int a, int b, int c) ; head[a] = cnt;
}int n, m, sum, ans;
int k, f[maxn];
inline bool debug(int k)
int pre[maxn], nxt[maxn];
std::vectorv[maxn];
int dfn[maxn], rnk[maxn], idx, fa[maxn];
int up[maxn];
void dfs1(int u, int fa = 0)
}}inline void work(int u, int fa)
nxt[begin] = 0;
pre[0] = begin;
nxt[sz - 1] = end;
pre[end] = sz - 1;
while (r < end && l < r) else l = nxt[l];
if (l == r) r = nxt[r];
}if (0 <= pre[end] && pre[end] < sz) rem = v[pre[end]];
else rem = 0;
#undef end
#undef begin
}if (u != 1)
}inline bool check(int mid)
return f[1] >= m;
}namespace work1
for (int i = head[u]; i; i = e[i].nxt) }}
int main()
}namespace work2 }}
bool check(int mid)
}return res >= m;
}int main() else r = mid - 1;
}printf("%d\n", ans);
return 0;
}}inline bool cmp(int a, int b)
bool flag = true;
int main()
if (m == 1)
if (flag)
dfs1(1);
std::sort(rnk + 1, rnk + n + 1, cmp);
int l = 1, r = sum / m;
while (l <= r) else r = mid - 1;
}printf("%d\n", ans);
return 0;
}
NOIP2018校模擬賽 T1 階乘
有n個正整數a i 設它們乘積為p,你可以給p乘上乙個正整數q,使p q剛好為正整數m的階乘,求m的最小值。共兩行。第一行乙個正整數n。第二行n個正整數a i 共一行乙個正整數m。16 看到這個題目描述只有一行我心頭就湧上一股不祥的預感 一般這種題 都比較 那啥 是的,這個題我又寫炸了 好的讓我們來...
雅禮 noip2018 模擬賽 day3 T3
典型樹形dp 這裡,我們應該看到一些基本性質 如果這個邊不能改 不是沒有必要改 我們就不改,因為就算改過去還要改回來,顯然不是最優的 注意 不能改 是指邊的性質和要求的相同而不包括對邊的顏色沒有要求的情況!如果我們每翻轉一條邊,就認為將這條邊的兩個端點度數 1,那麼不難看到,最後翻轉的所有邊構成的路...
NOIP2018 T1 鋪設道路
題目描述 春春是一名道路工程師,負責鋪設一條長度為 nn 的道路。鋪設道路的主要工作是填平下陷的地表。整段道路可以看作是 nn 塊首尾相連的區域,一開始,第 ii 塊區域下陷的深度為 d idi 春春每天可以選擇一段連續區間 l,r l,r 填充這段區間中的每塊區域,讓其下陷深度減少 11。在選擇區...