Guest User

Untitled

a guest
Jun 9th, 2024
243
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.92 KB | None | 0 0
  1. #include "bits/stdc++.h"
  2. using namespace std;
  3. #include <ext/pb_ds/assoc_container.hpp>
  4. #include <ext/pb_ds/tree_policy.hpp>
  5. using namespace __gnu_pbds;
  6. template<class key, class cmp = std::less<key>>
  7. using op_set = tree<key, null_type, cmp, rb_tree_tag, tree_order_statistics_node_update>;
  8. #ifdef thunder
  9. #include "bug.h"
  10. #else
  11. #define bug(...)
  12. #endif
  13.  
  14. #define ll long long
  15. #define lld double
  16. #define all(x) x.begin(), x.end()
  17. #define iceil(n, x) (((n) + (x) - 1) / (x))
  18.  
  19. const ll INF=2e18;
  20. const ll mod=998244353;
  21. const ll maxn=1e5+5;
  22.  
  23. template< ll mod >
  24. struct ModInt {
  25. ll x;
  26. ModInt() : x(0) {}
  27. ModInt(int64_t y) : x(y >= 0 ? y % mod : (mod - (-y) % mod) % mod) {}
  28. ModInt &operator+=(const ModInt &p) {
  29. if((x += p.x) >= mod) x -= mod;
  30. return *this;
  31. }
  32. ModInt &operator-=(const ModInt &p) {
  33. if((x += mod - p.x) >= mod) x -= mod;
  34. return *this;
  35. }
  36. ModInt &operator*=(const ModInt &p) {
  37. x = (int) (1LL * x * p.x % mod);
  38. return *this;
  39. }
  40. ModInt &operator/=(const ModInt &p) {
  41. *this *= p.inverse();
  42. return *this;
  43. }
  44. ModInt operator-() const { return ModInt(-x); }
  45. ModInt operator+(const ModInt &p) const { return ModInt(*this) += p; }
  46. ModInt operator-(const ModInt &p) const { return ModInt(*this) -= p; }
  47. ModInt operator*(const ModInt &p) const { return ModInt(*this) *= p; }
  48. ModInt operator/(const ModInt &p) const { return ModInt(*this) /= p; }
  49. bool operator<(const ModInt &p) const { return x < p.x; }
  50. bool operator>(const ModInt &p) const { return x > p.x; }
  51. bool operator==(const ModInt &p) const { return x == p.x; }
  52. bool operator!=(const ModInt &p) const { return x != p.x; }
  53. string to_str() { return to_string(x); }
  54. ModInt inverse() const {
  55. ll a = x, b = mod, u = 1, v = 0, t;
  56. while(b > 0) {
  57. t = a / b;
  58. swap(a -= t * b, b);
  59. swap(u -= t * v, v);
  60. }
  61. return ModInt(u);
  62. }
  63. ModInt pow(int64_t n) const {
  64. ModInt ret(1), mul(x);
  65. while(n > 0) {
  66. if(n & 1LL) ret *= mul;
  67. mul *= mul;
  68. n >>= 1LL;
  69. }
  70. return ret;
  71. }
  72. friend ostream &operator<<(ostream &os, const ModInt &p) {
  73. return os << p.x;
  74. }
  75. friend istream &operator>>(istream &is, ModInt &a) {
  76. int64_t t;
  77. is >> t;
  78. a = ModInt< mod >(t);
  79. return (is);
  80. }
  81. static ll get_mod() { return mod; }
  82. };
  83. using mint = ModInt< mod >;
  84.  
  85. template <typename node, typename update>
  86. struct segTree{
  87. ll len;
  88. vector<node> t;
  89. vector<update> u;
  90. vector<bool> lazy;
  91. vector<ll> tl,tr;
  92. node identity_element;
  93. update identity_transformation;
  94.  
  95. template<typename T>
  96. segTree(T &a){
  97. len = a.size();
  98. t.resize(4 * len);
  99. u.resize(4 * len);
  100. lazy.resize(4 * len);
  101. tl.resize(4 * len);
  102. tr.resize(4 * len);
  103. identity_element = node();
  104. identity_transformation = update();
  105. build(a,1,0,len-1);
  106. }
  107.  
  108. template <typename T>
  109. void build(const T &a, const ll &v, const ll &l, const ll &r){
  110. tl[v]=l;
  111. tr[v]=r;
  112. if (l == r){
  113. t[v]=a[l];
  114. return;
  115. }
  116. ll tm = (l + r) >> 1;
  117. build(a, v << 1, l, tm);
  118. build(a, v << 1 | 1, tm + 1, r);
  119. t[v].merge(t[v << 1], t[v << 1 | 1]);
  120. }
  121.  
  122. void apply(const ll &v, update val){
  123. if (tl[v] != tr[v]){
  124. lazy[v] = 1;
  125. u[v].combine(val, tl[v], tr[v]);
  126. }
  127. val.apply(t[v], tl[v], tr[v]);
  128. }
  129.  
  130. void pushdown(const ll &v){
  131. if(lazy[v]){
  132. apply(v << 1, u[v]);
  133. apply(v << 1 | 1, u[v]);
  134. u[v] = identity_transformation;
  135. lazy[v] = 0;
  136. }
  137. }
  138.  
  139. // rupd = range update
  140. void rupd(const ll &v,const ll &l, const ll &r, update val){
  141. if (l > tr[v] || r < tl[v])
  142. return;
  143. if (tl[v] >= l && tr[v] <= r){
  144. apply(v,val);
  145. return;
  146. }
  147. pushdown(v);
  148. rupd(v << 1, l, r, val);
  149. rupd(v << 1 | 1, l, r, val);
  150. t[v].merge(t[v << 1], t[v << 1 | 1]);
  151. }
  152.  
  153. node query(const ll &v,const ll &l, const ll &r){
  154. if (l > tr[v] || r < tl[v])
  155. return identity_element;
  156. if (tl[v] >= l && tr[v] <= r)
  157. return t[v];
  158. pushdown(v);
  159. node a,b,ans;
  160. a=query(v*2,l,r);
  161. b=query(v*2+1,l,r);
  162. ans.merge(a,b);
  163. return ans;
  164. }
  165. node query(const ll &l, const ll &r){
  166. return query(1, l, r);
  167. }
  168. void rupd(const ll &l, const ll &r, update upd){
  169. rupd(1, l, r, upd);
  170. }
  171. };
  172.  
  173. struct node1{
  174. mint prosum=0;
  175. mint asum=0;
  176. mint bsum=0;
  177. // use more variables if you want more information
  178. // these default values should be identity_element
  179.  
  180. node1() {}
  181. node1(pair<ll,ll> p){
  182. prosum=(p.first*p.second);
  183. asum=p.first;
  184. bsum=p.second;
  185. }
  186. void merge(const node1 &l, const node1 &r){
  187. prosum=(l.prosum+r.prosum);
  188. asum=(l.asum+r.asum);
  189. bsum=(l.bsum+r.bsum);
  190. }
  191. };
  192. struct update1{
  193. mint v=0;
  194. mint type=-1;
  195. // use more variables if you want more information
  196. // these default values should be identity_transformation
  197.  
  198. update1() {}
  199. update1(ll val,ll t){
  200. v=val;
  201. type=t;
  202. }
  203. // combine the current update1 with the other update1
  204. void combine(update1 &other, const ll &tl, const ll &tr){
  205. // only needed for range updates
  206. if(other.type==1){
  207. type=1;
  208. }else if(other.type==2){
  209. type=2;
  210. }
  211. v+=other.v;
  212. }
  213. // store the correct information in the node1 x
  214. void apply(node1 &x, const ll &tl, const ll &tr){
  215. if(type==1){
  216. x.asum=(x.asum+(v*(tr-tl+1)));
  217. x.prosum=(x.prosum+(v*x.bsum));
  218. }else if(type==2){
  219. x.bsum=(x.bsum+(v*(tr-tl+1)));
  220. x.prosum=(x.prosum+(v*x.asum));
  221. }
  222. }
  223. };
  224.  
  225. void solve(){
  226. ll n,q;
  227. cin>>n>>q;
  228. vector<pair<ll, ll>> ab(n+5);
  229. for(ll i=1;i<=n;i++){
  230. cin>>ab[i].first;
  231. }
  232. for(ll i=1;i<=n;i++){
  233. cin>>ab[i].second;
  234. }
  235. segTree<node1,update1> st(ab);
  236. while(q--){
  237. ll t;
  238. cin>>t;
  239. if(t==1){
  240. ll l,r;
  241. cin>>l>>r;
  242. ll x;
  243. cin>>x;
  244. st.rupd(l,r,update1(x,1));
  245. }else if(t==2){
  246. ll l,r;
  247. cin>>l>>r;
  248. ll x;
  249. cin>>x;
  250. st.rupd(l,r,update1(x,2));
  251. }else{
  252. ll l,r;
  253. cin>>l>>r;
  254. cout<<st.query(l,r).prosum<<'\n';
  255. }
  256. }
  257. }
  258.  
  259. signed main(){
  260. ios_base::sync_with_stdio(false), cin.tie(nullptr);
  261. //freopen("input.txt","r",stdin);
  262. //freopen("output.txt","w",stdout);
  263. int t=1;
  264. // cin>>t;
  265. for(int i=1;i<=t;i++){
  266. solve();
  267. }
  268. return 0;
  269. }
Advertisement
Add Comment
Please, Sign In to add comment