#line 2 "nachia\\multi-dimensional\\two-d-rectangle-query.hpp" #include #include #include #include namespace nachia{ template struct TwoDRectangleQuery{ private: struct BitVectorRank { using u64 = ::std::uint64_t; using u32 = ::std::uint32_t; static u32 popcountll(u64 c){ #ifdef __GNUC__ return __builtin_popcountll(c); #else c = (c & (~0ull/3)) + ((c >> 1) & (~0ull/3)); c = (c & (~0ull/5)) + ((c >> 2) & (~0ull/5)); c = (c & (~0ull/17)) + ((c >> 4) & (~0ull/17)); c = (c * (~0ull/255)) >> 56; return c; #endif } ::std::vector<::std::pair> a; BitVectorRank(const ::std::vector& b = {}){ int n = b.size(); a.assign(n/64 + 1, ::std::make_pair((u64)0, (u32)0)); auto p = b.begin(); u32 sum = 0; u64 tmp = 0; for(int i=0; i<=n; i+=64){ tmp = 0; int maxd = ::std::min(n - i, 64); for(int d=0; d> 6]; return (u32)(popcountll(b & ~(~u64(0) << (i & 63)))) + s; } bool get(::std::uint32_t i) const { return (a[i >> 6].first >> (i & 63)) & 1; } }; int n; int N; int logN; ::std::vector Xsorted; ::std::vector Ysorted; ::std::vector rankX; ::std::vector<::std::vector> Idx; ::std::vector Z; ::std::vector L; public: TwoDRectangleQuery(const ::std::vector<::std::pair>& pos){ n = pos.size(); ::std::vector sortIY(n); for(int i=0; i sortIX(n); rankX.resize(n); for(int i=0; i(n,-1)); L.resize(logN); Z.resize(logN); for(int i=0; i=0; i--){ ::std::vector Lbuf(n,0); auto& preList = Idx[i+1]; int z = ((n >> (i+1)) << i) + ::std::min(1< get_update_points(int v) const { ::std::vector res(logN+1); int p = rankX[v]; int d = logN; while(d > 0){ res[d] = { d,p }; d--; if(L[d].get(p)) p = L[d].rank(p); else p = Z[d] + p - L[d].rank(p); } res[d] = {d,p}; return res; } struct Query{ int d,l,r; }; ::std::vector get_ranges_from_idx(int xl, int xr, int yl, int yr){ ::std::vector res; struct Search{ int i, xa, xb, ys, yt; }; ::std::vector Q; res.reserve((logN+1)*2); Q.reserve((logN+1)*2); Q.push_back({ logN,0,n,yl,yr }); for(int i=0; i<(int)Q.size(); i++){ auto p = Q[i]; if(p.xa == p.xb) continue; if(xr <= p.xa || p.xb <= xl) continue; if(xl <= p.xa && p.xb <= xr){ res.push_back({ p.i, p.ys, p.yt }); continue; } p.i--; int nxs = L[p.i].rank(p.ys), nxt = L[p.i].rank(p.yt); Q.push_back({ p.i,p.xa,p.xa+(1< get_ranges(PosX xl, PosX xr, PosY yl, PosY yr){ return get_ranges_from_idx( lower_bound(Xsorted.begin(),Xsorted.end(),xl) - Xsorted.begin(), lower_bound(Xsorted.begin(),Xsorted.end(),xr) - Xsorted.begin(), lower_bound(Ysorted.begin(),Ysorted.end(),yl) - Ysorted.begin(), lower_bound(Ysorted.begin(),Ysorted.end(),yr) - Ysorted.begin() ); } }; } // namespace nachia #line 2 "Main.cpp" #include #include #line 7 "Main.cpp" #include using namespace std; using i32 = int32_t; using u32 = uint32_t; using i64 = int64_t; using u64 = uint64_t; #define rep(i,n) for(int i=0; i<(int)(n); i++) int main(){ int N, Q; cin >> N >> Q; vector> A(N); rep(i,N){ A[i].first = i; cin >> A[i].second; } nachia::TwoDRectangleQuery d2(A); vector> rqs(d2.get_segment_count()); rep(i,rqs.size()){ rqs[i].resize(N+1); rep(j,N) rqs[i][j+1] = rqs[i][j] + A[d2.to_vtx(i, j)].second; } rep(i,Q){ int l,r,x; cin >> l >> r >> x; l--; i64 sum = (i64)x * (r - l); for(auto q : d2.get_ranges(l, r, 0, x)) sum += rqs[q.d][q.r] - rqs[q.d][q.l] - (i64)x * (q.r - q.l); cout << sum << '\n'; } return 0; } struct ios_do_not_sync{ ios_do_not_sync(){ std::ios::sync_with_stdio(false); std::cin.tie(nullptr); } } ios_do_not_sync_instance;