fork download
  1. #include<bits/stdc++.h>
  2.  
  3. using namespace std;
  4. #define ll long long
  5. #define MAX 100100
  6. #define pb push_back
  7.  
  8. int n,q;
  9. vector<tuple<int,int,int> > adj[MAX];
  10. int head[MAX], w[MAX], depth[MAX], treesize[MAX], pos[MAX], parent[MAX], root[MAX], w1[MAX], a[MAX];
  11. int cnt = 0, cur = 0;
  12. int sum[(int)3e6], lc[(int)3e6], rc[(int)3e6];
  13. ll d[MAX];
  14.  
  15. int build(int l, int r)
  16. {
  17. int pos = ++cur;
  18. if(l == r){
  19. sum[pos] = 0;
  20. lc[pos] = -1;
  21. rc[pos] = -1;
  22. return pos;
  23. }else{
  24. int m = (l+r)>>1;
  25. sum[pos] = 0;
  26. lc[pos] = build(l,m);
  27. rc[pos] = build(m+1,r);
  28. return pos;
  29. }
  30. }
  31.  
  32. int update(int l, int r, int po, int prev)
  33. {
  34. int pos = ++cur;
  35. if(l == r){
  36. sum[pos] = sum[prev] + 1;
  37. lc[pos] = -1;
  38. rc[pos] = -1;
  39. return pos;
  40. }else{
  41. int m = (l+r)>>1;
  42. if(po <= m){
  43. lc[pos] = update(l,m,po,lc[prev]);
  44. rc[pos] = rc[prev];
  45. sum[pos] = sum[lc[pos]] + sum[rc[pos]];
  46. }else{
  47. rc[pos] = update(m+1,r,po,rc[prev]);
  48. lc[pos] = lc[prev];
  49. sum[pos] = sum[lc[pos]] + sum[rc[pos]];
  50. }
  51. return pos;
  52. }
  53. }
  54.  
  55. int get(int nodl, int nodr, int l, int r, int u, int v)
  56. {
  57. if(r < u || v < l) return 0;
  58. if(u <= l && r <= v) return nodr[sum] - nodl[sum];
  59. int m = (l+r)>>1;
  60. return get(lc[nodl],lc[nodr],l,m,u,v) + get(rc[nodl], rc[nodr],m+1,r,u,v);
  61. }
  62.  
  63. void nhap()
  64. {
  65. cin >> n >> q;
  66. for(int i = 0; i<n-1; i++){
  67. int a,b,c,d; cin >> a >> b >> c >> d;
  68. adj[a].pb(make_tuple(b,c,d));
  69. adj[b].pb(make_tuple(a,c,d));
  70. }
  71. parent[1] = 0;
  72. depth[1] = 0;
  73. w[1] = 0;
  74. d[1] = 0;
  75. }
  76.  
  77. void dfs(int v)
  78. {
  79. int index = -1;
  80. treesize[v] = 1;
  81. for(int i = 0; i< adj[v].size(); i++) if(get<0>(adj[v][i]) != parent[v]){
  82. int u = get<0>(adj[v][i]);
  83. parent[u] = v;
  84. w[u] = get<2>(adj[v][i]);
  85. w1[u] = get<1>(adj[v][i]);
  86. depth[u] = depth[v] + 1;
  87. d[u] = d[v] + get<1>(adj[v][i]);
  88. dfs(u);
  89. treesize[v] += treesize[u];
  90. if(index == -1 || treesize[u] > treesize[get<0>(adj[v][index])]) index = i;
  91. }
  92. if(index != 0 && index != -1) swap(adj[v][0], adj[v][index]);
  93. }
  94.  
  95. void decompose(int v, int h)
  96. {
  97. head[v] = h;
  98. pos[v] = ++cnt;
  99. for(tuple<int,int,int> x : adj[v]) if(get<0>(x) != parent[v]){
  100. if(get<0>(x) == get<0>(adj[v][0])) decompose(get<0>(x),h);
  101. else decompose(get<0>(x), get<0>(x));
  102. }
  103. }
  104.  
  105. void process()
  106. {
  107. dfs(1);
  108. decompose(1,1);
  109. root[0] = build(1,1e5);
  110. for(int i = 1; i<=n; i++) a[pos[i]] = w[i];
  111. for(int i = 1; i<=n; i++) root[i] = update(1,1e5,a[i],root[i-1]);
  112. while(q--){
  113. int u,v,k,y; cin >> u >> v >> k >> y;
  114. int _u = u;
  115. int _v = v;
  116. int dem = 0;
  117. while(head[u] != head[v]){
  118. if(depth[head[u]] < depth[head[v]]) swap(u,v);
  119. dem += get(root[pos[head[u]] -1], root[pos[u]],1,1e5,y,y);
  120. u = parent[head[u]];
  121. }
  122. if(depth[u] > depth[v]) swap(u,v);
  123. ll sum = d[_u] + d[_v] - 2*d[u];
  124. dem += get(root[pos[u]], root[pos[v]],1,1e5,y,y);
  125. dem = depth[_u] + depth[_v] - 2*depth[u] - dem;
  126. if(dem <= k){
  127. cout << sum << '\n';
  128. }else{
  129. cout << -1 << '\n';
  130. }
  131. }
  132. }
  133.  
  134. int main()
  135. {
  136. ios_base::sync_with_stdio(0); cin.tie(0);
  137. nhap();
  138. process();
  139. }
  140.  
Success #stdin #stdout 0.01s 20740KB
stdin
4 3
1 2 5 1
2 3 3 2
3 4 4 1
1 4 1 1
1 4 0 1
1 4 2 3
stdout
12
-1
-1