E. Non-Decreasing Dilemma

传送门:CF

前言:嗯,看了题解就是一个普通的线段树,所以就是硬搞,嗯,搞,嗯,搞,嗯,搞。

于是一晚上的美好时间就被这道题搞没了......

具有纪念意义的AC代码如下:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
struct AC {
	ll ln, rn, ls, rs, v;
};
int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	int n, m;
	cin >> n >> m;
	vector<int>v(n + 1);
	for (int i = 1; i <= n; i++) {
		cin >> v[i];
	}
	vector<AC>tre(n << 3);
	function<void(int, int, int)>build = [&](int l, int r, int a) {
		if (l == r) {
			tre[a] = { v[l],v[r],1,1,1 };
			return;
		}
		int mid = (l + r) >> 1;
		build(l, mid, (a << 1));
		build(mid + 1, r, (a << 1) | 1);
		tre[a].ln = tre[(a << 1)].ln;
		tre[a].rn = tre[(a << 1) | 1].rn;
		if (tre[(a << 1)].rn <= tre[(a << 1) | 1].ln) {
			tre[a].v = tre[a << 1].v + tre[(a << 1) | 1].v + (tre[a << 1].rs*tre[(a << 1) | 1].ls);
			if (tre[(a << 1) | 1].rs >= (r - mid)) {
				tre[a].rs = tre[(a << 1) | 1].rs + tre[a << 1].rs;
			}
			else {
				tre[a].rs = tre[(a << 1) | 1].rs;
			}
			if (tre[a << 1].ls >= (mid - l + 1)) {
				tre[a].ls = tre[a << 1].ls + tre[(a << 1) | 1].ls;
			}
			else {
				tre[a].ls = tre[(a << 1)].ls;
			}
		}
		else {
			tre[a].v = tre[a << 1].v + tre[(a << 1) | 1].v;
			tre[a].ls = tre[a << 1].ls;
			tre[a].rs = tre[(a << 1) | 1].rs;
		}


	};
	build(1, n, 1);
	function<void(int, int, int, int, int)>update = [&](int pos, int t, int l, int r, int a) {
		int mid = (l + r) >> 1;
		if (l == r) {
			tre[a] = { t,t,1,1,1 };
			v[pos] = t;
		
			return;
		}
		if (pos <= mid) {
			update(pos, t, l, mid, (a << 1));
		}
		else {
			update(pos, t, mid + 1,r,(a << 1) | 1);
		}
		tre[a].ln = tre[(a << 1)].ln;
		tre[a].rn = tre[(a << 1) | 1].rn;
		if (tre[(a << 1)].rn <= tre[(a << 1) | 1].ln) {
			tre[a].v = tre[a << 1].v + tre[(a << 1) | 1].v + (tre[a << 1].rs*tre[(a << 1) | 1].ls);
			if (tre[(a << 1) | 1].rs >= (r - mid)) {
				tre[a].rs = tre[(a << 1) | 1].rs + tre[a << 1].rs;
			}
			else {
				tre[a].rs = tre[(a << 1) | 1].rs;
			}
			if (tre[a << 1].ls >= (mid - l + 1)) {
				tre[a].ls = tre[a << 1].ls + tre[(a << 1) | 1].ls;
			}
			else {
				tre[a].ls = tre[a << 1].ls;
			}
		}
		else {
			tre[a].v = tre[a << 1].v + tre[(a << 1) | 1].v;
			tre[a].ls = tre[a << 1].ls;
			tre[a].rs = tre[(a << 1) | 1].rs;
		}
	};
	function<ll(int, int,int ,int,int)>query = [&](int l, int r,int a,int L,int R) {
		//cout << l << ' ' << r << ' ' << a << ' ' << L << ' ' << R << ' ' << tre[a].v << '\n';
		if (l >= L && r <= R)return tre[a].v;
		int mid = (l + r) >> 1;
		if (L <= mid && R > mid) {
			ll kase1 = query(l, mid, a << 1, L, R);
			ll kase2 = query(mid + 1, r, (a << 1) | 1, L, R);
			ll kase;
		//	cout << "find::" << tre[a<<1].rs<<' '<<tre[(a<<1)|1].ls<<' '<<kase1<<' '<<kase2<<endl;
		//	cout << tre[(a << 1) | 1].ln << ' ' << tre[(a << 1) | 1].rn << endl;
			if (tre[(a << 1)].rn <= tre[(a << 1) | 1].ln) {
				kase=kase1+kase2+ (min(tre[a << 1].rs,(ll)(mid-L+1))*min(tre[(a << 1) | 1].ls,(ll)(R-mid)));
			}
			else {
				kase = kase1 + kase2;
			}
			return kase;
		}
		else {
			if (L <= mid) {
				return  query(l, mid, a << 1, L, R);
			}
			else {
				return query(mid + 1, r, (a << 1) | 1, L, R);
			}
		}
		
	};
	while (m--) {
		int op;
		cin >> op;
		if (op == 1) {
			int pos, t;
			cin >> pos >> t;
			update(pos, t, 1, n, 1);
		}
		else {
			int l, r;
			cin >> l >> r;
			cout << query(1,n,1,l, r) << '\n';
		}
	}
	return 0;
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值