diff --git a/src/20241111/20241111solution.pdf b/src/20241111/20241111solution.pdf new file mode 100644 index 0000000..1005db5 Binary files /dev/null and b/src/20241111/20241111solution.pdf differ diff --git a/src/20241111/U101804.cpp b/src/20241111/U101804.cpp new file mode 100644 index 0000000..294989d --- /dev/null +++ b/src/20241111/U101804.cpp @@ -0,0 +1,3 @@ +int main(){ + +} \ No newline at end of file diff --git a/src/20241111/U101804.md b/src/20241111/U101804.md new file mode 100644 index 0000000..9b5c7c6 --- /dev/null +++ b/src/20241111/U101804.md @@ -0,0 +1,71 @@ +这个问题涉及树的遍历和动态更新,需要我们计算路径得分的期望。由于每个修改都可能影响某条路径的期望得分,因此要高效地处理初始计算和后续更新。 + +### 解题思路: + +1. **树的构建**: + - 给定父节点数组,可以构建一棵以 $1$ 为根的有根树。用一个邻接表来存储子节点信息。 + +2. **初始状态下期望得分的计算**: + - 使用深度优先搜索(DFS)计算期望得分。 + - 从根节点出发,递归计算每个节点的得分期望,遵循给定的转移概率 $\frac{w_v}{\text{sum}_u}$。 + - 对于一个节点 $u$,其期望得分 $E(u)$ 可以递归计算为: + \[ + E(u) = a_u + \sum_{v \in \text{children of } u} \frac{w_v}{\text{sum}_u} \cdot E(v) + \] + +3. **处理修改操作**: + - 每次修改某个节点 $u$ 的 $w$ 或 $a$ 值后,需要更新与 $u$ 相关的所有路径的期望。 + - 直接重新运行DFS在大规模数据($n, q \leq 100,000$)中代价过高,因此需使用某种增量更新方法。 + - 可以使用**树链剖分**或**树状数组**来高效更新受影响的子树或路径。 + +4. **取模运算**: + - 由于结果需要对 $998244353$ 取模,所有的运算,包括除法,都需要用模逆元处理。 + - 对于 $p$ 是素数,$x$ 的逆元为 $x^{p-2} \bmod p$,使用快速幂算法计算。 + +### 具体步骤: + +1. **预处理**: + - 构建树并计算初始期望得分 $E(1)$。 + - 用 DFS 遍历每个节点计算期望得分的初始值。 + +2. **更新操作**: + - 修改 $u$ 的 $w$ 或 $a$ 值后,调整 $u$ 的父节点期望,并递归更新到根节点。 + - 使用自底向上的路径更新机制,通过父节点的影响逐步更新。 + +3. **实现细节**: + - 采用链式前向星或邻接表存储树结构。 + - 使用分块思想或其他树状数据结构如**树链剖分**,以便快速定位并更新路径。 + +### 复杂度分析: + +- **时间复杂度**:初始期望计算为 $O(n)$,每次修改和更新平均为 $O(\log n)$ 或更低,具体取决于使用的数据结构。 +- **空间复杂度**:$O(n)$ 用于存储树结构和权值数组。 + +### 实现关键点: + +- **DFS 计算期望**: + ```cpp + void dfs(int u) { + E[u] = a[u]; + for (int v : children[u]) { + dfs(v); + E[u] += (w[v] * E[v]) / sum_u; // 注意使用模逆元 + } + } + ``` + +- **更新期望**: + ```cpp + void update(int u, int new_w, int new_a) { + w[u] = new_w; + a[u] = new_a; + // 使用树状数组或其他机制更新相关路径的期望 + } + ``` + +### 注意事项: + +- 确保处理浮点除法时使用模运算。 +- 根据问题的规模,考虑使用平衡树或线段树来优化更新操作。 + +这个解法需要巧妙地结合树结构和概率论来计算路径上的期望,并进行高效的更新。 \ No newline at end of file diff --git a/src/20241111/U75662.cpp b/src/20241111/U75662.cpp index 107fc9e..4048c04 100644 --- a/src/20241111/U75662.cpp +++ b/src/20241111/U75662.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -10,19 +11,27 @@ using ll = int64_t; -const ll max_m = 1e3 + 5, max_n = max_m, inf = std::numeric_limits::max(); +const ll max_m = 1e4 + 5, max_n = max_m, inf = std::numeric_limits::max(); ll n, m, s, dists[max_n]; struct Edge{ ll u,v,x,y,t; }edges[max_m]; int main(){ + std::iostream::sync_with_stdio(false), std::cin.tie(nullptr), std::cout.tie(nullptr); + std::fill(dists, dists+max_n, inf); std::cin>>n>>m>>s; dists[s]=0; for(ll i{1};i<=m;i++){ + + const auto swap_big_small = [](T &a, T &b)->void{ + if(a>b){std::swap(a,b);} + }; std::cin>>edges[i].u>>edges[i].v>>edges[i].x>>edges[i].y>>edges[i].t; + swap_big_small(edges[i].u, edges[i].v); + swap_big_small(edges[i].x, edges[i].y); } std::priority_queue, std::vector>, std::greater<>> pq;