結果

問題 No.3411 Range Clamp Sum
コンテスト
ユーザー shobonvip
提出日時 2025-12-26 16:13:43
言語 C++17
(gcc 15.2.0 + boost 1.89.0)
結果
AC  
実行時間 4,465 ms / 10,000 ms
コード長 6,060 bytes
記録
記録タグの例:
初AC ショートコード 純ショートコード 純主流ショートコード 最速実行時間
コンパイル時間 2,613 ms
コンパイル使用メモリ 223,164 KB
実行使用メモリ 223,624 KB
最終ジャッジ日時 2025-12-26 16:15:04
合計ジャッジ時間 66,561 ms
ジャッジサーバーID
(参考情報)
judge5 / judge3
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 2
other AC * 28
権限があれば一括ダウンロードができます

ソースコード

diff #
raw source code

/**
	author:  shobonvip
	created: 2025.12.26 15:57:19
**/

#include<bits/stdc++.h>


#include<atcoder/segtree>
template <typename S, S (*op)(S, S), S (*e)(), typename IntType>
struct range_tree {
		typedef std::pair<IntType, IntType> Point;
	public:		
		range_tree() {}

		void add_point(IntType a, IntType b) {
			points.emplace_back(Point{a, b});
		}

		std::vector<Point> merge_points(std::vector<Point> &a, std::vector<Point> &b) {
			std::vector<Point> ret((int)a.size() + (int)b.size());
			int piv = 0;
			int piva = 0;
			int pivb = 0;
			while (piva < (int)a.size() || pivb < (int)b.size()) {
				if (piva == (int)a.size()) {
					ret[piv++] = b[pivb++];
				}else if(pivb == (int)b.size()){
					ret[piv++] = a[piva++];
				}else{
					if (a[piva].second <= b[pivb].second) {
						assert(a[piva].first < b[pivb].first);
						ret[piv++] = a[piva++];
					}else{
						ret[piv++] = b[pivb++];
					}
				}
			}
			assert(piv == (int)a.size() + (int)b.size());
			return ret;
		}

		void build() {
			std::sort(points.begin(), points.end());
			points.erase(unique(points.begin(), points.end()), points.end());

			if (points.empty()) return;


			IntType memo = points[0].first;
			xlist.emplace_back(memo);
			std::vector<std::vector<Point>> tmp_idy(1, std::vector<Point>(1,points[0]));
			for (int i=1; i<(int)points.size(); i++){
				if (points[i].first != memo) {
					assert(memo < points[i].first);
					tmp_idy.emplace_back(std::vector<Point>(1, points[i]));
					memo = points[i].first;
					xlist.emplace_back(memo);
				}else{
					tmp_idy.back().emplace_back(points[i]);
				}
			}

			assert(tmp_idy.size() == xlist.size());

			n = (int)xlist.size();
			sz = 1;
			while (sz < n) {
				sz <<= 1;
			}

			idy.resize(2 * sz);
			seg.resize(2 * sz);
			for (int i=0; i<(int)xlist.size(); i++){
				idy[i+sz] = tmp_idy[i];
				seg[i+sz] = atcoder::segtree<S,op,e>((int)idy[i+sz].size());
			}

			for (int i=sz-1; i>=1; i--){
				idy[i] = merge_points(idy[2*i], idy[2*i+1]);
				seg[i] = atcoder::segtree<S,op,e>((int)idy[i].size());
			}
		}

		int y_lower_bound(std::vector<Point> &a, IntType q) {
			int ub = (int)a.size() + 1;
			int lb = 0;
			while (ub - lb > 1) {
				int t = (ub + lb) / 2;
				if (q > a[t-1].second) {
					lb = t;
				}else{
					ub = t;
				}
			}

			return lb;
		}

		int yx_lower_bound(std::vector<Point> &a, Point &p) {
			int ub = (int)a.size() + 1;
			int lb = 0;
			while (ub - lb > 1) {
				int t = (ub + lb) / 2;
				if (p.second > a[t-1].second || (p.second == a[t-1].second && p.first > a[t-1].first)) {
					lb = t;
				}else{
					ub = t;
				}
			}

			return lb;
		}

		S get(IntType x, IntType y) {
			Point p = Point{x, y};
			int i = lower_bound(points.begin(), points.end(), p) - points.begin();
			if (i == (int)points.size()) return e();
			if (points[i] != p) return e();
			return seg[1].get(yx_lower_bound(idy[1], p));
		}

		S prod_inner(int ind, IntType d, IntType u) {
			int di = y_lower_bound(idy[ind], d);
			int ui = y_lower_bound(idy[ind], u);
			return seg[ind].prod(di, ui);		
		}

		S prod(IntType l, IntType r, IntType d, IntType u) {
			int li = lower_bound(xlist.begin(), xlist.end(), l) - xlist.begin();
			int ri = lower_bound(xlist.begin(), xlist.end(), r) - xlist.begin();
			li += sz;
			ri += sz;
			S retl = e(), retr = e();
			while (li < ri) { 
				if (li & 1) {
					retl = op(retl, prod_inner(li, d, u));
					li++;
				}
				if (ri & 1){
					ri--;
					retr = op(prod_inner(ri, d, u), retr);
				}
				li >>= 1;
				ri >>= 1;
			}
			return op(retl, retr);
		}

		void set(IntType x, IntType y, S val) {
			Point p = Point{x, y};
			int i = lower_bound(points.begin(), points.end(), p) - points.begin();
			assert (i < (int)points.size());
			assert (points[i] == p);
			int xi = lower_bound(xlist.begin(), xlist.end(), p.first) - xlist.begin();
			xi += sz;
			while (xi > 0) {
				seg[xi].set(yx_lower_bound(idy[xi], p), val);
				xi >>= 1;
			}
		}

	private:
		int n, sz;
		std::vector<Point> points;
		std::vector<IntType> xlist;
		std::vector<std::vector<Point>> idy;
		std::vector<atcoder::segtree<S,op,e>> seg;
};



using namespace std;
typedef long long ll;
#define rep(i, s, n) for (int i = (int)(s); i < (int)(n); i++)
#define rrep(i, s, n) for (int i = (int)(n)-1; i >= (int)(s); i--)
#define all(v) v.begin(), v.end()

template <typename T> bool chmin(T &a, const T &b) {
	if (a <= b) return false;
	a = b;
	return true;
}

template <typename T> bool chmax(T &a, const T &b) {
	if (a >= b) return false;
	a = b;
	return true;
}

template <typename T> T max(vector<T> &a){
	assert(!a.empty());
	T ret = a[0];
	for (int i=0; i<(int)a.size(); i++) chmax(ret, a[i]);
	return ret;
}

template <typename T> T min(vector<T> &a){
	assert(!a.empty());
	T ret = a[0];
	for (int i=0; i<(int)a.size(); i++) chmin(ret, a[i]);
	return ret;
}

template <typename T> T sum(vector<T> &a){
	T ret = 0;
	for (int i=0; i<(int)a.size(); i++) ret += a[i];
	return ret;
}


ll op(ll a, ll b){
	return a + b;
}
ll e(){
	return 0;
}

int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);

	int n, q;
	cin >> n >> q;
	vector<int> a(n);
	range_tree<ll,op,e,int> seg0;
	range_tree<ll,op,e,int> seg1;
	rep(i,0,n) {
		cin >> a[i];
		seg0.add_point(i, a[i]);
		seg1.add_point(i, a[i]);
	}

	vector<int> t(q),x(q),y(q),l(q),r(q),d(q),u(q);
	rep(i,0,q) {
		cin >> t[i];
		if (t[i] == 1) {
			cin >> x[i] >> y[i];
			x[i]--;
			seg0.add_point(x[i], y[i]);
			seg1.add_point(x[i], y[i]);
		} else {
			cin >> l[i] >> r[i] >> d[i] >> u[i];
			l[i]--;
		}
	}

	seg0.build();
	seg1.build();

	rep(i,0,n) {
		seg0.set(i, a[i], + 1);
		seg1.set(i, a[i], + a[i]);
	}

	rep(i,0,q) {
		if (t[i] == 1) {
			seg0.set(x[i], a[x[i]], 0);
			seg1.set(x[i], a[x[i]], 0);
			a[x[i]] = y[i];
			seg0.set(x[i], a[x[i]], + 1);
			seg1.set(x[i], a[x[i]], + a[x[i]]);
		} else {
			ll ans = 0;
			ans += seg1.prod(l[i], r[i], d[i], u[i]);
			ans += ll(d[i]) * seg0.prod(l[i], r[i], int(-1e9), d[i]);
			ans += ll(u[i]) * seg0.prod(l[i], r[i], u[i], int(1e9));
			cout << ans << '\n';
		}
	}
}

0