update
This commit is contained in:
parent
b9b726c22f
commit
dfdf354730
BIN
src/20241111/20241111solution.pdf
Normal file
BIN
src/20241111/20241111solution.pdf
Normal file
Binary file not shown.
3
src/20241111/U101804.cpp
Normal file
3
src/20241111/U101804.cpp
Normal file
@ -0,0 +1,3 @@
|
||||
int main(){
|
||||
|
||||
}
|
71
src/20241111/U101804.md
Normal file
71
src/20241111/U101804.md
Normal file
@ -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;
|
||||
// 使用树状数组或其他机制更新相关路径的期望
|
||||
}
|
||||
```
|
||||
|
||||
### 注意事项:
|
||||
|
||||
- 确保处理浮点除法时使用模运算。
|
||||
- 根据问题的规模,考虑使用平衡树或线段树来优化更新操作。
|
||||
|
||||
这个解法需要巧妙地结合树结构和概率论来计算路径上的期望,并进行高效的更新。
|
@ -2,6 +2,7 @@
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
#include <istream>
|
||||
#include <limits>
|
||||
#include <ostream>
|
||||
#include <queue>
|
||||
@ -10,19 +11,27 @@
|
||||
|
||||
using ll = int64_t;
|
||||
|
||||
const ll max_m = 1e3 + 5, max_n = max_m, inf = std::numeric_limits<ll>::max();
|
||||
const ll max_m = 1e4 + 5, max_n = max_m, inf = std::numeric_limits<ll>::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 = []<class T>(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::pair<ll, ll>, std::vector<std::pair<ll, ll>>, std::greater<>> pq;
|
||||
|
Loading…
Reference in New Issue
Block a user