\(\text{Knowledge}\)
-
【\(5\)】深度优先遍历
-
【\(4\)】图
-
【\(1\)】代数 \((\)初中部分\()\)
\(\text{Solution}\)
首先我们进行分类讨论。
没有边权的边对答案没有意义,因此当 \(op=0\) 时我们不添加这条边。
诸如 \(\tt ABC396\) 的 \(\tt E\),当每个独立的树中一个树的任何一个点确定时,所有点都确定。所以,所有点都可以表示为 \(a_1\) 的变化,考虑 \(a_1\) 的数据范围。
列不等式。
\[\sum w-a_1\geq l,\sum w-a_1\leq r
\]
则:\(a_1\le l-w,a_1\ge r-w\)。
令 \(n_1\) 为不等式 \(1\) 的最大值,\(n_2\) 为不等式 \(2\) 的最大值。
我们惊人的发现,对于 \(a_1\) 路径模 \(2\) 等于 \(1\),顺序反了,因此调换两者即可。最后乘上 \(\max(\min(n_2)-\max(n_1)+1,0)\) 即可。
\(\text{Code}\)
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int md = 1e9 + 7;
int _,n,l,r;
vector<pair<int,int>> g[200005];
int f[200005];
int mi,ma;
void dfs(int u,int w,int s)
{f[u] = 1;int nl = l - w,nr = r - w;if (s == -1){swap(nl,nr);nl = -nl;nr = -nr;}mi = max(mi,nl);ma = min(ma,nr);for (auto k : g[u]){if (!f[k.first]){dfs(k.first,k.second - w,-s);}}
}
void solve()
{cin >> n >> l >> r;for (int i = 1;i <= n;i++) {g[i].clear();f[i] = 0;}for (int i = 1,op,u,v,w;i < n;i++){cin >> op >> u >> v; if (!op) continue;cin >> w;g[u].push_back({v,w});g[v].push_back({u,w});}int ans = 1;for (int i = 1;i <= n;i++){if (!f[i]){mi = l,ma = r;dfs(i,0,1);ans = ans * max(0ll,ma - mi + 1);ans %= md;}}cout << ans << '\n';
}
signed main()
{ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);cin >> _;while (_--) solve();return 0;
}