#pragma once
// SPDX-License-Identifier: MIT// This file includes code derived from hitonanode/cplib-cpp:// https://github.com/hitonanode/cplib-cpp/blob/99e4d0494958b4176c449c28c80a985b12b6791b/data_structure/rectangle_add_rectangle_sum.hpp//// Original copyright:// Copyright (c) 2019 Ryotaro Sato//// Local modifications in this repository:// - Adjusted names and style to match this repository.// - Made this header self-contained by adding missing standard library includes.#include<algorithm>
#include<tuple>
#include<utility>
#include<vector>usingnamespacestd;#include"../data-structure/binary-indexed-tree.hpp"template<classI,classT>classRectangleAddRectangleSum{structAddQuery{Ixl,xr,yl,yr;Tval;};structSumQuery{Ixl,xr,yl,yr;};vector<AddQuery>add_queries;vector<SumQuery>sum_queries;public:RectangleAddRectangleSum()=default;voidadd_rectangle(Ixl,Ixr,Iyl,Iyr,Tval){add_queries.push_back(AddQuery{xl,xr,yl,yr,val});}voidadd_query(Ixl,Ixr,Iyl,Iyr){sum_queries.push_back(SumQuery{xl,xr,yl,yr});}vector<T>solve()const{vector<I>ys;for(constauto&a:add_queries){ys.push_back(a.yl);ys.push_back(a.yr);}sort(ys.begin(),ys.end());ys.erase(unique(ys.begin(),ys.end()),ys.end());constintY=ys.size();vector<tuple<I,int,int>>ops;for(intq=0;q<int(sum_queries.size());++q){ops.emplace_back(sum_queries[q].xl,0,q);ops.emplace_back(sum_queries[q].xr,1,q);}for(intq=0;q<int(add_queries.size());++q){ops.emplace_back(add_queries[q].xl,2,q);ops.emplace_back(add_queries[q].xr,3,q);}sort(ops.begin(),ops.end());BinaryIndexedTree<T>b00(Y),b01(Y),b10(Y),b11(Y);vector<T>ret(sum_queries.size());for(autoo:ops){intqtype=get<1>(o),q=get<2>(o);if(qtype>=2){constAddQuery&query=add_queries.at(q);inti=lower_bound(ys.begin(),ys.end(),query.yl)-ys.begin();intj=lower_bound(ys.begin(),ys.end(),query.yr)-ys.begin();Tx=get<0>(o);Tyi=query.yl,yj=query.yr;if(qtype&1)swap(i,j),swap(yi,yj);b00.add(i,x*yi*query.val);b01.add(i,-x*query.val);b10.add(i,-yi*query.val);b11.add(i,query.val);b00.add(j,-x*yj*query.val);b01.add(j,x*query.val);b10.add(j,yj*query.val);b11.add(j,-query.val);}else{constSumQuery&query=sum_queries.at(q);inti=lower_bound(ys.begin(),ys.end(),query.yl)-ys.begin();intj=lower_bound(ys.begin(),ys.end(),query.yr)-ys.begin();Tx=get<0>(o);Tyi=query.yl,yj=query.yr;if(qtype&1)swap(i,j),swap(yi,yj);i--,j--;ret[q]+=b00.sum(i)+b01.sum(i)*yi+b10.sum(i)*x+b11.sum(i)*x*yi;ret[q]-=b00.sum(j)+b01.sum(j)*yj+b10.sum(j)*x+b11.sum(j)*x*yj;}}returnret;}};
#line 2 "data-structure-2d/rectangle-add-rectangle-sum.hpp"
// SPDX-License-Identifier: MIT// This file includes code derived from hitonanode/cplib-cpp:// https://github.com/hitonanode/cplib-cpp/blob/99e4d0494958b4176c449c28c80a985b12b6791b/data_structure/rectangle_add_rectangle_sum.hpp//// Original copyright:// Copyright (c) 2019 Ryotaro Sato//// Local modifications in this repository:// - Adjusted names and style to match this repository.// - Made this header self-contained by adding missing standard library includes.#include<algorithm>
#include<tuple>
#include<utility>
#include<vector>usingnamespacestd;#line 2 "data-structure/binary-indexed-tree.hpp"
template<typenameT>structBinaryIndexedTree{intN;vector<T>data;BinaryIndexedTree()=default;BinaryIndexedTree(intsize){init(size);}voidinit(intsize){N=size+2;data.assign(N+1,{});}// get sum of [0,k]Tsum(intk)const{if(k<0)returnT{};// return 0 if k < 0Tret{};for(++k;k>0;k-=k&-k)ret+=data[k];returnret;}// getsum of [l,r]inlineTsum(intl,intr)const{returnsum(r)-sum(l-1);}// get value of kinlineToperator[](intk)const{returnsum(k)-sum(k-1);}// data[k] += xvoidadd(intk,Tx){for(++k;k<N;k+=k&-k)data[k]+=x;}// range add x to [l,r]voidimos(intl,intr,Tx){add(l,x);add(r+1,-x);}// minimize i s.t. sum(i) >= wintlower_bound(Tw){if(w<=0)return0;intx=0;for(intk=1<<__lg(N);k;k>>=1){if(x+k<=N-1&&data[x+k]<w){w-=data[x+k];x+=k;}}returnx;}// minimize i s.t. sum(i) > wintupper_bound(Tw){if(w<0)return0;intx=0;for(intk=1<<__lg(N);k;k>>=1){if(x+k<=N-1&&data[x+k]<=w){w-=data[x+k];x+=k;}}returnx;}};/**
* @brief Binary Indexed Tree(Fenwick Tree)
*/#line 21 "data-structure-2d/rectangle-add-rectangle-sum.hpp"
template<classI,classT>classRectangleAddRectangleSum{structAddQuery{Ixl,xr,yl,yr;Tval;};structSumQuery{Ixl,xr,yl,yr;};vector<AddQuery>add_queries;vector<SumQuery>sum_queries;public:RectangleAddRectangleSum()=default;voidadd_rectangle(Ixl,Ixr,Iyl,Iyr,Tval){add_queries.push_back(AddQuery{xl,xr,yl,yr,val});}voidadd_query(Ixl,Ixr,Iyl,Iyr){sum_queries.push_back(SumQuery{xl,xr,yl,yr});}vector<T>solve()const{vector<I>ys;for(constauto&a:add_queries){ys.push_back(a.yl);ys.push_back(a.yr);}sort(ys.begin(),ys.end());ys.erase(unique(ys.begin(),ys.end()),ys.end());constintY=ys.size();vector<tuple<I,int,int>>ops;for(intq=0;q<int(sum_queries.size());++q){ops.emplace_back(sum_queries[q].xl,0,q);ops.emplace_back(sum_queries[q].xr,1,q);}for(intq=0;q<int(add_queries.size());++q){ops.emplace_back(add_queries[q].xl,2,q);ops.emplace_back(add_queries[q].xr,3,q);}sort(ops.begin(),ops.end());BinaryIndexedTree<T>b00(Y),b01(Y),b10(Y),b11(Y);vector<T>ret(sum_queries.size());for(autoo:ops){intqtype=get<1>(o),q=get<2>(o);if(qtype>=2){constAddQuery&query=add_queries.at(q);inti=lower_bound(ys.begin(),ys.end(),query.yl)-ys.begin();intj=lower_bound(ys.begin(),ys.end(),query.yr)-ys.begin();Tx=get<0>(o);Tyi=query.yl,yj=query.yr;if(qtype&1)swap(i,j),swap(yi,yj);b00.add(i,x*yi*query.val);b01.add(i,-x*query.val);b10.add(i,-yi*query.val);b11.add(i,query.val);b00.add(j,-x*yj*query.val);b01.add(j,x*query.val);b10.add(j,yj*query.val);b11.add(j,-query.val);}else{constSumQuery&query=sum_queries.at(q);inti=lower_bound(ys.begin(),ys.end(),query.yl)-ys.begin();intj=lower_bound(ys.begin(),ys.end(),query.yr)-ys.begin();Tx=get<0>(o);Tyi=query.yl,yj=query.yr;if(qtype&1)swap(i,j),swap(yi,yj);i--,j--;ret[q]+=b00.sum(i)+b01.sum(i)*yi+b10.sum(i)*x+b11.sum(i)*x*yi;ret[q]-=b00.sum(j)+b01.sum(j)*yj+b10.sum(j)*x+b11.sum(j)*x*yj;}}returnret;}};