Submission #917230

#TimeUsernameProblemLanguageResultExecution timeMemory
917230thangdz2k7Fish 2 (JOI22_fish2)C++17
100 / 100
1712 ms38484 KiB
#include <bits/stdc++.h>
using namespace std;
const long long inf = 1e15 + 5;
const int N = 1e5 + 5;
int n, q;
long long a[N];
set<int> rp[N], lp[N];
namespace ST {
	pair<int, int> t[N << 2];
	int lazy[N << 2];
	inline pair<int, int> operator+(const pair<int, int> &lhs, const pair<int, int> &rhs) {
		if (lhs.first != rhs.first) return min(lhs, rhs);
		return {lhs.first, lhs.second + rhs.second}; 
	}
	inline void push_up(int p) {
		t[p] = t[p << 1] + t[p << 1 | 1];
	}
	inline void tag(int p, int x) {
		t[p].first += x;
		lazy[p] += x;
	}
	inline void push_down(int p) {
		if (lazy[p]) {
			tag(p << 1, lazy[p]);
			tag(p << 1 | 1, lazy[p]);
			lazy[p] = 0;
		}
	}
	void build(int p, int l, int r) {
		t[p].second = r - l + 1;
		if (l == r) return;
		int mid = (l + r) >> 1;
		build(p << 1, l, mid);
		build(p << 1 | 1, mid + 1, r);
	}
	void modify(int p, int l, int r, int ll, int rr, int x) {
		if (l >= ll && r <= rr) {
			tag(p, x);
			return;
		}
		push_down(p);
		int mid = (l + r) >> 1;
		if (mid >= ll) modify(p << 1, l, mid, ll, rr, x);
		if (mid < rr) modify(p << 1 | 1, mid + 1, r, ll, rr, x);
		push_up(p);
	}
	pair<int, int> query(int p, int l, int r, int ll, int rr) {
		if (l >= ll && r <= rr) return t[p];
		push_down(p);
		int mid = (l + r) >> 1;
		if (mid >= ll && mid < rr) return query(p << 1, l, mid, ll, rr) + query(p << 1 | 1, mid + 1, r, ll, rr);
		if (mid >= ll) return query(p << 1, l, mid, ll, rr);
		return query(p << 1 | 1, mid + 1, r, ll, rr); 
	}
}
namespace BIT {
	long long c[N];
	inline void modify(int p, long long x) {
		for (; p <= n; p += p & -p)
			c[p] += x;
	}
	inline long long query(int p) {
		long long res = 0;
		for (; p; p -= p & -p)
			res += c[p];
		return res;
	}
	inline long long query(int l, int r) {
		return query(r) - query(l - 1);
	}
}
namespace ST1 {
	long long val[N << 2], lazy[N << 2];
	inline void push_up(int p) {
		val[p] = min(val[p << 1], val[p << 1 | 1]);
	}
	inline void tag(int p, long long x) {
		val[p] += x;
		lazy[p] += x;
	}
	inline void push_down(int p) {
		if (lazy[p]) {
			tag(p << 1, lazy[p]);
			tag(p << 1 | 1, lazy[p]);
			lazy[p] = 0;
		}
	}
	void modify(int p, int l, int r, int ll, int rr, long long x) {
		if (l >= ll && r <= rr) {
			tag(p, x);
			return;
		}
		push_down(p);
		int mid = (l + r) >> 1;
		if (mid >= ll) modify(p << 1, l, mid, ll, rr, x);
		if (mid < rr) modify(p << 1 | 1, mid + 1, r, ll, rr, x);
		push_up(p);
	}
	long long find_l(int p, int l, int r, int pos, long long x) {
		if (val[p] >= x) return -1;
		if (l == r) return l;
		push_down(p);
		int mid = (l + r) >> 1;
		if (pos <= mid) return find_l(p << 1, l, mid, pos, x);
		int res = find_l(p << 1 | 1, mid + 1, r, pos, x);
		return ~res ? res : find_l(p << 1, l, mid, pos, x); 
	}
	long long find_r(int p, int l, int r, int pos, long long x) {
		if (val[p] >= x) return -1;
		if (l == r) return l;
		push_down(p);
		int mid = (l + r) >> 1;
		if (pos > mid) return find_r(p << 1 | 1, mid + 1, r, pos, x);
		int res = find_r(p << 1, l, mid, pos, x);
		return ~res ? res : find_r(p << 1 | 1, mid + 1, r, pos, x);
	}
}
namespace ST2 {
	long long val[N << 2], lazy[N << 2];
	inline void push_up(int p) {
		val[p] = max(val[p << 1], val[p << 1 | 1]);
	}
	inline void tag(int p, long long x) {
		val[p] += x;
		lazy[p] += x;
	}
	inline void push_down(int p) {
		if (lazy[p]) {
			tag(p << 1, lazy[p]);
			tag(p << 1 | 1, lazy[p]);
			lazy[p] = 0;
		}
	}
	void modify(int p, int l, int r, int ll, int rr, long long x) {
		if (l >= ll && r <= rr) {
			tag(p, x);
			return;
		}
		push_down(p);
		int mid = (l + r) >> 1;
		if (mid >= ll) modify(p << 1, l, mid, ll, rr, x);
		if (mid < rr) modify(p << 1 | 1, mid + 1, r, ll, rr, x);
		push_up(p);
	}
	long long find_l(int p, int l, int r, int pos, long long x) {
		if (val[p] <= x) return -1;
		if (l == r) return l;
		push_down(p);
		int mid = (l + r) >> 1;
		if (pos <= mid) return find_l(p << 1, l, mid, pos, x);
		int res = find_l(p << 1 | 1, mid + 1, r, pos, x);
		return ~res ? res : find_l(p << 1, l, mid, pos, x); 
	}
	long long find_r(int p, int l, int r, int pos, long long x) {
		if (val[p] <= x) return -1;
		if (l == r) return l;
		push_down(p);
		int mid = (l + r) >> 1;
		if (pos > mid) return find_r(p << 1 | 1, mid + 1, r, pos, x);
		int res = find_r(p << 1, l, mid, pos, x);
		return ~res ? res : find_r(p << 1 | 1, mid + 1, r, pos, x);
	}
}
inline bool judge(int l, int r) {
	if (r - l <= 1) return false;
	return BIT::query(l + 1, r - 1) < min(a[l], a[r]);
}
void modify_seg(int l, int r, int x) {
	ST::modify(1, 1, n, l + 1, r - 1, x);
	if (x == 1) {
		lp[l].insert(r);
		rp[r].insert(l);
	} else {
		lp[l].erase(r);
		rp[r].erase(l);
	} 
}
int find_r(int l, int r) {
	return ST1::find_r(1, 0, n + 1, r + 1, BIT::query(l));
}
int find_l(int l, int r) {
	return ST2::find_l(1, 0, n + 1, l - 1, BIT::query(r - 1));
}
void check(int pos, int x) {
	int l = pos - 1, r = pos + 1;
	while (true) {
		if (judge(l, r)) modify_seg(l, r, x);
		if (l == 0 && r == n + 1) break;
		if (a[l] < a[r]) l = find_l(l, r);	
		else r = find_r(l, r);
	}
}
void modify(int pos, long long x) {
	check(pos, -1);
	BIT::modify(pos, x - a[pos]);
	ST1::modify(1, 0, n + 1, pos + 1, n + 1, x - a[pos]);
	ST1::modify(1, 0, n + 1, pos, pos, -(x - a[pos]));
	ST2::modify(1, 0, n + 1, pos, n + 1, x - a[pos]);
	ST2::modify(1, 0, n + 1, pos, pos, x - a[pos]);
	a[pos] = x;
	while (!rp[pos].empty()) {
		int l = *rp[pos].begin();
		modify_seg(l, pos, -1);
	}
	while (!lp[pos].empty()) {
		int r = *lp[pos].begin();
		modify_seg(pos, r, -1);
	}
	lp[pos].clear(), rp[pos].clear();
	int r = find_r(pos, pos + 1);
	while (true) {
		if (judge(pos, r)) modify_seg(pos, r, 1);
		if (r == n + 1) break;
		r = find_r(pos, r);
	} 
	int l = find_l(pos - 1, pos);
	while (true) {
		if (judge(l, pos)) modify_seg(l, pos, 1);
		if (l == 0) break;
		l = find_l(l, pos); 
	}
	check(pos, 1);
}
int main() {
	scanf("%d", &n);
	ST::build(1, 1, n);
	a[0] = a[n + 1] = inf;
	ST1::modify(1, 0, n + 1, n + 1, n + 1, -inf);
	ST2::modify(1, 0, n + 1, 0, 0, inf);
	modify_seg(0, n + 1, 1);
	long long tmp;
	for (int i = 1; i <= n; ++i)
		scanf("%lld", &tmp), modify(i, tmp);
	scanf("%d", &q);
	while (q--) {
		int op, x, y;
		scanf("%d%d%d", &op, &x, &y);
		if (op == 1) {
			modify(x, y);
		} else {
			int l = ST1::find_l(1, 0, n + 1, y, BIT::query(x - 1));
			int r = ST2::find_r(1, 0, n + 1, x, BIT::query(y));
			printf("%d\n", ST::query(1, 1, n, l, r).second);
		}
	}
	return 0;
}

Compilation message (stderr)

fish2.cpp: In function 'int main()':
fish2.cpp:225:7: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  225 |  scanf("%d", &n);
      |  ~~~~~^~~~~~~~~~
fish2.cpp:233:8: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  233 |   scanf("%lld", &tmp), modify(i, tmp);
      |   ~~~~~^~~~~~~~~~~~~~
fish2.cpp:234:7: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  234 |  scanf("%d", &q);
      |  ~~~~~^~~~~~~~~~
fish2.cpp:237:8: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  237 |   scanf("%d%d%d", &op, &x, &y);
      |   ~~~~~^~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...