Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <cstdio>
- #include <functional>
- #include <utility>
- #include <cmath>
- #include <algorithm>
- #include <cassert>
- #include <vector>
- #include <set>
- #include <queue>
- #include <map>
- #include <stack>
- #include <unordered_map>
- #include <string>
- #include <iterator>
- #include <iomanip>
- #include <fstream>
- #include <random>
- #include <chrono>
- using namespace std;
- #define uint unsigned int
- #define prll pair<ll,ll>
- #define prdd pair<double,double>
- #define m_p make_pair
- #define ticonst (ll)1337228
- #define INF (ll)1e18
- #define ll long long
- const ll q = 239053;
- const ll mod = 1e9 + 7;
- const ll mod2 = 1e9 + 13;
- const ll MAXN = 2e5 + 100;
- const ll MAXM = 4294967291;
- const ll L = 20;
- mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
- // if(clock() / (double)CLOCKS_PER_SEC >= t.0)
- ll tin[MAXN], tout[MAXN], sz[MAXN];
- ll up[MAXN][L];
- vector<prll> g[MAXN];
- ll head[MAXN], down[MAXN], pr[MAXN];
- ll n, m;
- void calc(ll a, ll p)
- {
- pr[a] = p;
- up[a][0] = p;
- for (ll i = 1; i < L; ++i)
- up[a][i] = up[up[a][i - 1]][i - 1];
- }
- vector<ll> r;
- ll t = 0;
- void dfs(ll v, ll p)
- {
- tin[v] = t++;
- calc(v, p);
- for (ll j = 0; j < (ll)g[v].size(); ++j)
- {
- ll to = g[v][j].first;
- if (to == p)
- continue;
- head[to] = (!j ? head[v] : to);
- ++down[head[to]];
- r[t] = g[v][j].second;
- dfs(to, v);
- }
- tout[v] = t++;
- }
- bool upper(ll a, ll b)
- {
- return (tin[a] <= tin[b] && tout[b] <= tout[a]);
- }
- ll lca(ll a, ll b)
- {
- if (upper(a, b))
- return a;
- if (upper(b, a))
- return b;
- for (ll i = L - 1; i >= 0; --i)
- if (!upper(up[a][i], b))
- a = up[a][i];
- return up[a][0];
- }
- void repair(ll v, ll p)
- {
- if (g[v][0].first == p)
- swap(g[v][0], g[v][(ll)g[v].size() - 1]);
- for (ll j = 0; j < (ll)g[v].size(); ++j)
- {
- ll to = g[v][j].first;
- if (to == p)
- continue;
- repair(to, v);
- sz[v] += sz[to];
- if (sz[to] > sz[g[v][0].first])
- swap(g[v][0], g[v][j]);
- }
- }
- struct SegTree
- {
- ll s;
- vector<vector<ll>> t;
- void update(ll v)
- {
- ll nwn = (ll)t[v * 2].size() + (ll)t[v * 2 + 1].size();
- t[v].resize(nwn);
- merge(t[v * 2].begin(), t[v * 2].end(), t[v * 2 + 1].begin(), t[v * 2 + 1].end(), t[v].begin());
- }
- void build(ll tl, ll tr, ll v, vector<ll> &a)
- {
- if (tl + 1 == tr)
- {
- t[v].push_back(a[tl]);
- return;
- }
- ll mid = (tr + tl) >> 1;
- build(tl, mid, v * 2, a);
- build(mid, tr, v * 2 + 1, a);
- update(v);
- }
- SegTree(vector<ll> &v)
- {
- ll dop = (ll)v.size();
- s = dop;
- t.resize(4 * s);
- build(0, s, 1, v);
- }
- ll get(ll tl, ll tr, ll l, ll r, ll v, ll x)
- {
- if (tl >= r || tr <= l)
- return 0;
- if (l <= tl && tr <= r)
- {
- auto it = upper_bound(t[v].begin(), t[v].end(), x);
- return it - t[v].begin();
- }
- ll mid = (tr + tl) >> 1;
- return get(tl, mid, l, r, v * 2, x) + get(mid, tr, l, r, v * 2 + 1, x);
- }
- ll get(ll l, ll r, ll x)
- {
- return get(0, s, l, r + 1, 1, x);
- }
- };
- ll k_pred(ll v, ll k)
- {
- for (ll i = L - 1; i >= 0; --i)
- {
- ll st = (1ll < i);
- if (st <= k)
- {
- k -= st;
- v = up[v][i];
- }
- }
- return v;
- }
- ll supa(ll &a, ll b, ll x, SegTree &u_tree)
- {
- if (head[a] == a)
- {
- ll aa = a;
- a = pr[a];
- return r[tin[aa]] <= x;
- }
- ll root = head[a];
- ll r = tin[a], l = max(tin[b], tin[root]);
- a = root;
- return u_tree.get(l + 1, r, x);
- }
- void $main()
- {
- cin >> n >> m;
- for (ll i = 0; i < n; ++i)
- sz[i] = 1;
- r.resize(2 * n + 100);
- for (ll i = 0; i < n - 1; ++i)
- {
- ll u, v, c; cin >> u >> v >> c;
- --u; --v;
- g[u].emplace_back(v, c);
- g[v].emplace_back(u, c);
- }
- repair(0, 0);
- dfs(0, 0);
- for (ll &el : r)
- if (!el)
- el = INF;
- SegTree tree = SegTree(r);
- for (ll i = 0; i < m; ++i)
- {
- ll u, v, x; cin >> u >> v >> x;
- --u; --v;
- ll _lca = lca(u, v);
- ll ans = 0;
- while (upper(_lca, u) && _lca != u)
- ans += supa(u, _lca, x, tree);
- while (upper(_lca, v) && _lca != v)
- ans += supa(v, _lca, x, tree);
- cout << ans << '\n';
- }
- }
- int main()
- {
- #ifndef ONLINE_JUDGE
- freopen("input.txt", "r", stdin);
- #else
- //freopen("wizard.in", "r", stdin);
- //freopen("wizard.out", "w", stdout);
- #endif
- ios_base::sync_with_stdio(0);
- cin.tie(0), cout.tie(0);
- $main();
- return 0;
- }
- //257593BA
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement