LOJ 6733 人造情感

2022-09-19 21:15:19 字數 4339 閱讀 5771

loj #6733. 人造情感

​ 先考慮如何求解 \(w(s)\)。設 \(f_u\) 為考慮子樹 \(u\) 內的路徑集合的 \(w\) 值,則有轉移

\[f_u=\max\left\_u}f_v\right\}\cup\left\(x,y)\and\operatorname_v\in \operatorname(x,y)}f_v\right\}

\]其中 \((x,y,w)\) 在給定的路經集合 \(u\) 中,且滿足條件 \(\operatorname(x,y)=u\)。直接做顯然就暴斃了,可以思考轉移的性質。

​ 觀察發現這個轉移涉及到「路徑下方所掛的點」的求和,於是我們可以想到樹上差分。令 \(f'_u=f_u-\sum\limits__u}f_v\),在上式中用 \(f'\) 替代 \(f\),於是轉移就變成了:

\[f'_u=\max\\cup\left\(x,y)\and v\neq u}f'_v\right\}

\]其中 \((x,y,w)\) 在給定的路經集合 \(u\) 中,且滿足條件 \(\operatorname(x,y)=u\)。

​ 於是現在只需實現單點加鏈求和就行了,可以用樹狀陣列維護 \(\operatorname\) 序,時間複雜度為 \(\mathcal o(n\log n)\)。

​ 接下來考慮如何計算 \(f(x,y)\)。注意到 \(f(x,y)=f_\mathrm-h_(x,y)}-\sum\limits_(x,y)\and \operatorname_u\in\operatorname(x,y)}f_\),其中 \(h_u\) 為考慮子樹 \(u\) 外的路徑集合的 \(w\) 值。後面涉及到「路徑下方所掛的點」的求和可以直接用樹上差分消掉,有 \(f(x,y)=f_}+\sum\limits_(x,y)}f'_u-f_(u,v)}-h_(u,v)}\)。前面有關 \(f,f'\) 的值是很容易就能求出來的,關鍵就是如何計算 \(h_\)。

​ 類似於處理 \(f\) 的方法,我們設 \(h'_u=h_u-h__u}-\sum\limits___u}\and v\neq u}f_\),那麼 \(h'\) 有和 \(f'\) 類似的轉移式。我們考慮列舉所有經過 \(\operatorname_u\) 但不經過 \(u\) 的路徑 \((x,y,w)\),設 \(z=\operatorname(x,y)\)。對於當前列舉的 \(u\),設 \(g'_v=\beginf'_v,\qquad v不是u的祖先\\h'_v,\qquad v是u的祖先\end\),容易發現路徑 \((x,y,w)\) 對 \(h'_u\) 的貢獻為 \(w-\sum\limits_(x,y)\and v\neq z}g'_v\)。於是我們就得到了乙個樸素的做法:先列舉結點 \(u\),然後列舉路徑集合 \(u\) 中經過 \(u\) 的路徑 \((x,y,w)\),在更新 \(g'\) 的同時計算貢獻。該做法的時間複雜度為 \(\mathcal o(n^2)\)。

​ 考慮優化。注意到 \(u\) 中的路徑 \((x,y,w)\) 只會對其下方掛著的所有點造成貢獻;更進一步,其對同乙個結點下掛著的所有兒子的貢獻是一樣的。設結點 \(u\) 在路徑 \((x,y)\) 上,結點 \(v\) 為結點 \(u\) 的乙個兒子,且滿足 \(v\) 不在路徑 \((x,y)\) 上。設 \(z=\operatorname(x,y)\),那麼該路徑對 \(v\) 的貢獻為

\[\beginw-(f_x-f_z)-(f_y-f_z),\qquad\qquad\qquad\qquad\! &(u=z)\\w-(f_x-f_u)-(f_y-f_z)-(h_u-h_z),&(u\in\operatorname(x,z)\and u\neq z)\\w-(f_x-f_z)-(f_y-f_u)-(h_u-h_z),&(u\in\operatorname(y,z)\and u\neq z)\end

\]其中 \(f,h\) 分別為 \(f',h'\) 在樹上的祖先和,即有 \(f_x=\sum\limits_(\mathrm,x)}f'_y\)。上式中的第二類和第三類可以合在一起討論,因此只需要討論 \(u=z\) 和 \(u\neq z\) 的情況。

時間複雜度為 \(\mathcal o((n+m)\log n)\)。

參考**

#include using namespace std;

template_tp &min_eq(_tp &x, const _tp &y)

template_tp &max_eq(_tp &x, const _tp &y)

static constexpr int mod = 998244353;

static constexpr int maxn = 3e5 + 5;

static constexpr int64_t inf = 0x3f3f3f3f3f3f3f3f;

int n, m;

int64_t ans;

vectorg[maxn];

namespace hld

} // hld::predfs1

void predfs2(int u, int topv) // hld::predfs2

inline int get_lca(int u, int v) // hld::get_lca

inline int get_anc(int u, int k) // hld::get_anc

inline void initialize(int root) // hld::initialize

} // namespace hld

using namespace hld;

namespace fen

inline void upd(int x, int64_t v)

inline int64_t ask(int x)

} // namespace fen

struct path pa[maxn];

vectorplca[maxn];

int64_t f[maxn], f[maxn], f1[maxn];

void dfs1(int u, int fa) // dfs1

void dfs11(int u, int fa) // dfs11

int64_t h[maxn], h[maxn], h1[maxn];

namespace sgt1 // sgt1::update

int64_t query(int p, int l, int r, int l, int r) // sgt1::query

inline void upd(int x, int64_t v)

inline int64_t ask(int l, int r)

} // namespace sgt1

namespace sgt2

void update(int p, int l, int r, int l, int r, int64_t v) // sgt2::update

int64_t query(int p, int l, int r, int x) // sgt2::query

inline void upd(int l, int r, int64_t v)

inline int64_t ask(int x)

} // namespace sgt2

void dfs2(int u, int fa) else if (xk == 0) else

}for (const int &v: g[u]) if (v != fa)

max_eq(h[v], sgt2::ask(label[v]));

} for (auto [x, y, w]: plca[u]) else if (xk == 0) else

} for (const int &v: g[u]) if (v != fa) dfs2(v, u);

} // dfs2

void dfs3(int u, int fa) // dfs3

int64_t sf[maxn];

void dfs4(int u, int fa) // dfs4

int main(void)

hld::initialize(1);

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

fen::clr(), dfs1(1, 0), dfs11(1, 0);

memset(sgt1::tr, -63, sizeof(sgt1::tr));

dfs2(1, 0), dfs3(1, 0);

ans = 0, dfs4(1, 0);

(ans += (int64_t)n * n % mod * (f1[1] % mod) % mod) %= mod;

printf("%lld\n", ans);

exit(exit_success);

} // main

6 7 3 實現列表函式

6.7.3 實現列表函式 剛才我們看到的篩選和對映函式,沒有展示如何實現,現在,我們要看乙個在第三章開始建立的函式。因為所有的列表處理函式都有類似的結構,看過下面的示例以後,實現其他任何函式也是可能的。在第三章,我們寫的函式,能夠計算列表中的所有元素的和或積 隨後,我們就意識到它可能比開始所表現的更...

南陽673 悟空的難題

描述 自從悟空當上了齊天大聖,花果山上的猴子猴孫們便也可以嚐到天上的各種仙果神酒,所以猴子猴孫們的體質也得到了很好的提高,身高年齡也得到了很大的提公升。有一天悟空沒事,要帶領他的猴子猴孫們出去旅遊,為了保持花果山的形象,一位年長的猴子建議猴子們都按身高排成一隊。猴子們是如此的著急出發,如何快速的排好...

NYOJ 673 悟空的難題

時間限制 1000 ms 記憶體限制 65535 kb難度 2 描述 自從悟空當上了齊天大聖,花果山上的猴子猴孫們便也可以嚐到天上的各種仙果神酒,所以猴子猴孫們的體質也得到了很好的提高,身高年齡也得到了很大的提公升。有一天悟空沒事,要帶領他的猴子猴孫們出去旅遊,為了保持花果山的形象,一位年長的猴子建...