「hnoi2015」接水果
給你乙個樹上路徑集合$ s $ ,每條路徑有個權值。每次詢問一條路徑 $ (x, y) $ ,問它在 $ s $ 中包含的路徑中權值第 $ k $ 小的是多少。
首先考慮如何判斷判斷一條路徑是否被另一條路徑包含。
當一條路徑 $ (x, y) (dep_x < dep_y) $ 是一條深度從淺到深的鏈時,路徑 $ (u, v) (dep_u < dep_v) $ 包含路徑 $ (x, y) $ 滿足 $ v $ 在 $ y $ 的子樹內、 $ u $ 在 $ x $ 的孩子、 $ y $ 的祖先 的子樹外, $ u, v $ 在樹的dfn序上為連續幾段。
當一條路徑 $ (x, y) (dep_x < dep_y) $ 不是一條深度從淺到深的鏈時,路徑 $ (u, v) $ 包含路徑 $ (x, y) $ 滿足 $ v $ 在 $ y $ 的子樹內、 $ u $ 在 $ x $ 的祖先 的子樹外, $ u, v $ 在樹的dfn序上為連續幾段。
然後樹套樹維護路徑 $ (x, y) $ 包含多少路徑,樹套樹維護即可。
對於每乙個詢問,我們都可以二分答案。將集合 $ s $ 中的路徑按權值排序,然後查詢其中包含的排名即可。我們發現這可以整體二分。時間複雜度 $ o(n \log^3) $
在luogu上開o2快如風,在loj上被1s時限卡自閉。。。
其實樹套樹可以用掃瞄線代替的,時間複雜度 $ o(n \log^2) $。
#include #define pb push_back
#define lnk(i, a) for(int i = hed[a]; i; i = nxt[i])
using namespace std;
const int n = 40010;
int n, m, q;
int cnt = 0, hed[n], to[n + n], nxt[n + n];
int dfn[n], low[n], idx = 0, fa[16][n], dep[n];
struct plate
}; plate a[n];
struct fruit
};int pp[n], lp = 0, ans[n];
namespace tree
inline bool operator<(const line &yy)const
}; line t[n * 20]; int tot = 0;
int tr[n];
inline void add(int x, int w)
inline int ask(int x)
inline void mdy(int x, int y, int xx, int yy, int w)
}void gi(int &x)
inline void add(int x, int y)
void dfs(int u, int ff)
int lca(int x, int y)
int find(int x, int y)
void solve(vectorq, int l, int r, int l, int r)
int mid = (l + r) >> 1, pos; vectorls, rs;
for(int i = l, lca, x, y; i <= r; ++i)
else
} sort(tree::t + 1, tree::t + tree::tot + 1); int j = 1;
for(int i = 0, k; i < q.size(); ++i)
for(; j <= tree::tot; ++j) tree::add(tree::t[j].y, tree::t[j].w);
tree::tot = 0;
solve(ls, l, mid, l, pos), solve(rs, mid + 1, r, pos + 1, r);
}int main()
sort(a + 1, a + m + 1), pp[++lp] = a[1].w;
for(int i = 2; i <= m; ++i) if(a[i].w ^ a[i - 1].w) pp[++lp] = a[i].w;
vectorq;
for(int i = 1, x, y, k; i <= q; ++i)
gi(x), gi(y), gi(k), q.pb((fruit));
sort(q.begin(), q.end());
solve(q, 1, lp, 1, m); for(int i = 1; i <= q; ++i) printf("%d\n", ans[i]);
return 0;
}
HNOI2015 開店 題解
目前只有開o2能過,stl的常數太大了,qwq 題意簡述,給你一棵樹,有點權與邊權,然後有很多詢問,每次詢問你點權在l r l r範圍內的點到給點點v v的距離之和。我們使用動態點分治來求取答案。先構建出點分樹,樹高肯定是在log nlog n級別內的,然後對於乙個分治點 重心 我們在上面記錄三個值...
HNOI2015實驗比較 題解
記得幾個月前自己曾經做過一道關於一張dag求排列的問題,現如今遇到了的是一道關於樹求排列的問題.這乙個問題看似簡單實際上有乙個細節那就是他可以取 這就使得複雜度公升高了.首先,最簡單的插孔原理。這乙個非常簡單,做這道題時,蒟蒻我現推式子。為什麼要解決這個問題呢,因為最基本的,在不考慮等於的情況下,n...
HNOI2015 菜餚製作 題解
傳送門 hnoi2015 菜餚製作 根據題目的描述,我們要做的首先是一步一步的分析 這個題肯定是拓撲排序無疑,因為要求的是滿足固定條件 有向圖的連邊 的某種排列,而難點就在於如何拓撲排序。根據題目的描述,我們首先想到的是根據字典序大小進行排序,那麼我們就舉例幾組資料來驗證一下是否正確,那麼先看下面這...