ABC133 速通
ABC133
A
随便做。
B
判断平方数。
C
如果 \(\lfloor\frac{L}{2019}\rfloor \not= \lfloor\frac{R}{2019}\rfloor\),则答案为 \(0\),否则暴力。
D
第一座山的水量是 \(A_1 + \frac{1}{2}\sum_{i=1}^n(-1)^iA_i\),后面递推。
E
令 \(dp_i\) 表示 \(i\) 子树以及固定 \(i\) 父亲颜色的答案,则:
\[dp_u = A_{k - 2}^{|E_u| - 1}\prod_{v \in E_u}dp_v
\]
答案即 \(A_k^{|E_{root}| + 1}\prod_{v \in E_{root}}dp_v\)。
F
对每一个颜色开一个 vector 记录对应颜色边的欧拉序,查询 \(dis_{u, root}\) 时,先把原 \(dis\) 算出来,再利用欧拉序得出系数,把对应颜色的边长修改即可。
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
#define MAXN 100005
#define MAXL 20
using ll = long long;
int n, q;
struct Edge
{
int u, v, c;
ll d;
} e[MAXN << 1];
int h[MAXN];
int idx = 0;
int fa[MAXL][MAXN], dep[MAXN];
ll dis[MAXN];
int dfn[MAXN], elt[MAXN << 1];
int eid = 0;
vector<int> eli[MAXN];
vector<ll> cnt[MAXN], sum[MAXN];
void add(int u, int v, int c, ll d)
{
e[++idx] = {h[u], v, c, d};
h[u] = idx;
e[++idx] = {h[v], u, c, d};
h[v] = idx;
}
void dfs(int p, int f)
{
fa[0][p] = f;
dep[p] = dep[f] + 1;
dfn[p] = eid;
for (int i = h[p]; i; i = e[i].u)
{
if (e[i].v == f)
{
continue;
}
elt[++eid] = i;
dis[e[i].v] = dis[p] + e[i].d;
dfs(e[i].v, p);
elt[++eid] = -i;
}
}
int lca(int u, int v)
{
if (u == v)
{
return u;
}
if (dep[u] != dep[v])
{
if (dep[u] < dep[v])
{
swap(u, v);
}
for (int i = MAXL - 1; ~i; i--)
{
if (dep[fa[i][u]] > dep[v])
{
u = fa[i][u];
}
}
u = fa[0][u];
}
if (u == v)
{
return u;
}
for (int i = MAXL - 1; ~i; i--)
{
if (fa[i][u] != fa[i][v])
{
u = fa[i][u];
v = fa[i][v];
}
}
return fa[0][u];
}
ll solve(int p, int u, ll v)
{
ll res = dis[p];
int idx = upper_bound(eli[u].begin(), eli[u].end(), dfn[p]) - eli[u].begin() - 1;
if (idx < 0)
{
return res;
}
return res - sum[u][idx] + v * cnt[u][idx];
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cin >> n >> q;
for (int i = 1; i < n; i++)
{
int u, v, c;
ll d;
cin >> u >> v >> c >> d;
add(u, v, c, d);
}
dfs(1, 1);
for (int k = 1; k < MAXL; k++)
{
for (int i = 1; i <= n; i++)
{
fa[k][i] = fa[k - 1][fa[k - 1][i]];
}
}
for (int i = 1; i <= eid; i++)
{
if (elt[i] > 0)
{
int c = e[elt[i]].c;
eli[c].push_back(i);
if (cnt[c].size())
{
cnt[c].push_back((*cnt[c].rbegin()) + 1);
sum[c].push_back((*sum[c].rbegin()) + e[elt[i]].d);
}
else
{
cnt[c].push_back(1);
sum[c].push_back(e[elt[i]].d);
}
}
else
{
int c = e[-elt[i]].c;
eli[c].push_back(i);
cnt[c].push_back((*cnt[c].rbegin()) - 1);
sum[c].push_back((*sum[c].rbegin()) - e[-elt[i]].d);
}
}
while (q--)
{
int x, y, u;
ll v;
cin >> u >> v >> x >> y;
int l = lca(x, y);
cout << solve(x, u, v) + solve(y, u, v) - 2 * solve(l, u, v) << '\n';
}
cout.flush();
return 0;
}


浙公网安备 33010602011771号