fork download
  1. #pragma GCC optimize("O3")
  2. #pragma GCC optimize("Ofast")
  3. #pragma GCC optimize("unroll-loops")
  4. #include <bits/stdc++.h>
  5. using namespace std;
  6. #define ll long long
  7. #define db double
  8. #define is insert
  9. #define pb push_back
  10. #define eb emplace_back
  11. #define pii pair<int, int>
  12. #define pll pair<long long, long long>
  13. #define X first
  14. #define Y second
  15. #define vi vector<int>
  16. #define vpi vector<pair<int, int>>
  17. #define msi multiset<int>
  18. #define int long long
  19. const int m83 = 998244353;
  20. const int m97 = (int)1e9+7;
  21. const int N = 200005;
  22. const int K = 5;
  23. const int inf = (int)1e18;
  24.  
  25. int n, q, pa[N], dep[N], tin[N], tout[N] ,sz[N], cid[N], ch[N], arr[N], nxt[N], curc, curid, timer = 1, pos[N];
  26. pii a[N];
  27. vi adj[N];
  28.  
  29. pii merge(pii f1, pii f2){
  30. int a = (f2.X * f1.X) % m83;
  31. int b = (f2.X * f1.Y + f2.Y) % m83;
  32. return {a,b};
  33. }
  34.  
  35. int dfs(int u, int p) {
  36. sz[u] = 1;
  37. pa[u] = p;
  38. dep[u] = ( p <0 ? 0: dep[p]+1);
  39. int mx = 0;
  40. nxt[u] = 0;
  41. for (int v: adj[u]){
  42. if(v != p){
  43. int s = dfs(v,u);
  44. sz[u] += s;
  45. if (s > mx) {
  46. mx = s;
  47. nxt[u] = v;
  48. }
  49. }
  50. }
  51. return sz[u];
  52. }
  53.  
  54. void decompose(int u, int h){
  55. ch[u] = h;
  56. pos[u] = ++curid;
  57. arr[curid] = u;
  58. if (nxt[u]) decompose(nxt[u], h);
  59. for(int v: adj[u]){
  60. if (v!=pa[u] && v!=nxt[u]){
  61. decompose(v, v);
  62. }
  63. }
  64. }
  65.  
  66. pii stl[4*N], str[4*N];
  67.  
  68. void build(int id, int l, int r){
  69. if(l == r){
  70. stl[id] = str[id] = a[arr[l]];
  71. return;
  72. }
  73. int mid = (l + r) >> 1;
  74. build(2*id, l, mid);
  75. build(2*id+1, mid+1, r);
  76. stl[id] = merge(stl[2*id], stl[2*id+1]);
  77. str[id] = merge(str[2*id+1], str[2*id]);
  78. }
  79.  
  80.  
  81. void update(int id, int l, int r, int pos, pii val){
  82. if(l > pos || r < pos) return;
  83. if(l == pos && r == pos){
  84. stl[id] = str[id] = val;
  85. return;
  86. }
  87. int mid = (l + r) >> 1;
  88. update(2*id, l, mid, pos, val);
  89. update(2*id+1, mid+1, r, pos, val);
  90. stl[id] = merge(stl[2*id], stl[2*id+1]);
  91. str[id] = merge(str[2*id+1], str[2*id]);
  92. }
  93.  
  94. pii getl(int id, int l, int r, int u, int v){
  95. if(u > r || v < l) return {1, 0};
  96. if(u <= l && r <= v){
  97. return stl[id];
  98. }
  99. int mid = (l + r) >> 1;
  100. return merge(getl(2*id, l, mid, u, v), getl(2*id+1, mid+1, r, u, v));
  101. }
  102.  
  103. pii getr(int id, int l, int r, int u, int v){
  104. if(u > r || v < l) return {1, 0};
  105. if(u <= l && r <= v){
  106. return str[id];
  107. }
  108. int mid = (l + r) >> 1;
  109. return merge(getr(2*id+1, mid+1, r, u, v), getr(2*id, l, mid, u, v));
  110. }
  111.  
  112. void path(int u, int v, vpi& up, vpi& dn) {
  113. while (ch[u] != ch[v]){
  114. if (dep[ch[u]] >= dep[ch[v]]) {
  115. up.eb(pos[ch[u]], pos[u]);
  116. u = pa[ch[u]];
  117. }
  118. else{
  119. dn.eb(pos[ch[v]], pos[v]);
  120. v = pa[ch[v]];
  121. }
  122. }
  123. if (dep[u] <= dep[v]) {
  124. dn.eb(pos[u], pos[v]);
  125. }
  126. else{
  127. up.eb(pos[v], pos[u]);
  128. }
  129. }
  130.  
  131. void solve(){
  132. cin >> n >> q;
  133. for(int i=1, x, y; i<=n; i++){
  134. cin >> x >> y;
  135. x %= m83;
  136. y %= m83;
  137. a[i] = {x, y};
  138. }
  139. for(int i=1, u, v; i<n; i++){
  140. cin >> u >> v;
  141. adj[u].pb(v);
  142. adj[v].pb(u);
  143. }
  144. curc = 1;
  145. curid = 0;
  146. dfs(1, -1);
  147. decompose(1, 1);
  148. build(1, 1, n);
  149. while(q--){
  150. int t; cin >> t;
  151. if(t == 0){
  152. int p, x, y; cin >> p >> x >> y;
  153. update(1, 1, n, pos[p], {x, y});
  154. }
  155. else{
  156. int u, v, x; cin >> u >> v >> x;
  157. vpi up, dn;
  158. path(u, v, up, dn);
  159. int ca = 1, cb = 0;
  160. reverse(dn.begin(), dn.end());
  161. for(pii p : up){
  162. pii f = getr(1, 1, n, p.X, p.Y);
  163. tie(ca, cb) = merge({ca, cb}, f);
  164. }
  165. for(pii p : dn){
  166. pii f = getl(1, 1, n, p.X, p.Y);
  167. tie(ca, cb) = merge({ca, cb}, f);
  168. }
  169. int ans = (ca * x + cb) % m83;
  170. while(ans < 0) ans += m83;
  171. cout << ans << "\n";
  172. }
  173. }
  174. }
  175.  
  176. signed main(){
  177. // freopen("*.INP", "r", stdin);
  178. // freopen("*.OUT", "w", stdout);
  179. ios::sync_with_stdio(0);
  180. cin.tie(0); cout.tie(0);
  181. int tt = 1; //cin >> tt;
  182. while(tt--){
  183. solve();
  184. }
  185. }
  186.  
Success #stdin #stdout 0.01s 22080KB
stdin
4 3
1 5
4 0
1 1
3 2
1 3
2 4
3 4
1 1 4 3
0 3 2 1
1 4 4 4
stdout
29
14