Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- #define FASTER() ios_base::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL);
- #define ff first
- #define ss second
- #define pb push_back
- #define all(a) a.begin(), a.end()
- #define dbg(x) cerr<<" "<<#x<<" "<<x<<endl
- typedef long long ll;
- using namespace std;
- struct edge {
- int to, id;
- };
- struct Query {
- int l, r, id;
- };
- const int maxn = 1e5 + 13;
- const int k = 320;
- int n, t = -1;
- int cost[maxn];
- vector <pair <int, int>> lr;
- vector <edge> gr[maxn];
- vector <int> e;
- vector <pair <int, int>> tim;
- vector <Query> query;
- bool cmp (const Query &a, const Query &b) {
- int lf = a.l / k, ls = b.l / k;
- if(lf == ls) {
- if(a.r % 2 == 0) {
- return a.r < b.r;
- } else {
- return b.r < a.r;
- }
- }
- return lf < ls;
- }
- void euler(int v, int p) {
- tim[v].ff = t++;
- for(auto to : gr[v]) {
- if(to.to != p) {
- e.pb(to.id);
- lr[v].ff = e.size() -1;
- euler(to.to, v);
- e.pb(to.id);
- lr[v].ss = e.size() - 1;
- }
- }
- tim[v].ss = t++;
- }
- inline bool isUpper(int a, int b) {
- return (tim[a].ff <= tim[b].ff && tim[a].ss >= tim[b].ss);
- }
- void prin (set <int> &st) {
- int cnt = 0;
- for(auto a : st) {
- cout << a << ' ';
- cnt++;
- if(cnt == 10) break;
- }
- cout << endl;
- }
- struct MO {
- set <int> st;
- vector <int> used;
- unordered_map <int, int> cnt;
- int l, r;
- MO(int n) {
- l = 0;
- r = -1;
- used = vector <int>(n + 1, 0);
- for(int z = 0; z <= maxn; z++) {
- st.insert(z);
- }
- }
- void add(int id) {
- int x = cost[id];
- used[id]++;
- if(used[id] == 2) {
- cnt[x]--;
- if(cnt.count(x) == 0 || cnt[x] == 0) {
- st.insert(x);
- }
- } else {
- cnt[x]++;
- st.erase(x);
- }
- }
- void del(int id) {
- int x = cost[id];
- used[id]--;
- if(used[id] == 1) {
- cnt[x]++;
- } else {
- cnt[x]--;
- }
- if(used[id] == 1) {
- st.erase(x);
- } else if(cnt[x] == 0) {
- st.insert(x);
- }
- }
- inline int get() {
- return *st.begin();
- }
- };
- inline void addLeft(MO &goo) {
- goo.l--;
- goo.add(e[goo.l]);
- }
- inline void delLeft(MO &goo) {
- goo.del(e[goo.l]);
- goo.l++;
- }
- inline void addRight(MO &goo) {
- goo.r++;
- goo.add(e[goo.r]);
- }
- inline void delRight(MO &goo) {
- goo.del(e[goo.r]);
- goo.r--;
- }
- inline pair <int, int> getlr(int u, int v) {
- if(isUpper(u, v) || isUpper(v, u)) {
- int inff = tim[u].ff, inss = tim[v].ff;
- int outff = tim[u].ss, outss = tim[v].ss;
- if(inff > inss) swap(inff, inss);
- if(outff > outss) swap(outff, outss);
- if(abs(inss - inff) < abs(outss - outff)) {
- return {inff, inss};
- } else {
- return {outff, outss};
- }
- }
- if(tim[v].ss < tim[u].ff) {
- return {tim[v].ss, tim[u].ff};
- }
- return {tim[u].ss, tim[v].ff};
- }
- int main() {
- FASTER();
- int q;
- cin >> n >> q;
- lr.assign(n + 1, {-1, -1});
- tim.resize(n + 1);
- for(int i = 0; i < n - 1; i++) {
- int u, v, c;
- cin >> u >> v >> c;
- u--; v--;
- gr[u].pb({v, i});
- gr[v].pb({u, i});
- cost[i] = c;
- }
- euler(0, -1);
- tim[0] = {0, e.size() - 1};
- // for(auto a : e) cout << a + 1 << ' ';
- query.resize(q);
- for(int i = 0; i < q; i++) {
- int u, v;
- cin >> u >> v;
- u--; v--;
- auto tmp = getlr(u, v);
- int l = tmp.ff, r = tmp.ss;
- query[i] = {l, r, i};
- }
- sort(all(query), cmp);
- MO goo(n);
- vector <int> ans(q);
- for(int i = 0; i < q; i++) {
- auto qe = query[i];
- while(goo.r < qe.r) {
- addRight(goo);
- }
- while(goo.r > qe.r) {
- while(goo.l > qe.l) {
- addLeft(goo);
- }
- delRight(goo);
- }
- while(goo.l < qe.l) {
- while(goo.r < qe.r) {
- addRight(goo);
- }
- delLeft(goo);
- }
- while(goo.l > qe.l) {
- addLeft(goo);
- }
- ans[qe.id] = goo.get();
- }
- for(auto a : ans) cout << a << '\n';
- }
Advertisement
Add Comment
Please, Sign In to add comment