关于李超树的问题(玄关)
  • 板块学术版
  • 楼主Walrus
  • 当前回复0
  • 已保存回复0
  • 发布时间2024/7/15 11:49
  • 上次更新2024/7/15 14:02:38
查看原帖
关于李超树的问题(玄关)
908424
Walrus楼主2024/7/15 11:49

rt,如果某道题目的 ans 可能是负数但是我的李超树只会执行

PIII query(int p, int l, int r, int d) {
	if (r < d || d < l) return {0, 0};//<---这个
  ···
}

并且有提前 insert 一条很小的线段,不确定是不是这么 insert 的。

题目是 Codechef 的 The street。

in

10 10
3 5
1 3 8 3 1
3 5
1 5 10 -8 2
3 5
3 10
2 1 10 0 1
3 6
2 5 7 2 1
3 6

out

NA

7

7

-38\\<---就是这个负数也会输出 NA

11

14

所以说是啥问题,怎么解决?

附代码(建议无视 namespace SegmentTree 里的内容)

#include <bits/stdc++.h>
#define rep(i, j, k) for(int i = j; i <= k; ++i)
#define pre(i, j, k) for(int i = j; i >= k; --i)
#define pb push_back
#define PII pair<int, int>
#define fir first
#define sec second
#define int long long
#define y1 li_junyi
#define ls (p << 1)
#define rs (p << 1 | 1)

using namespace std;
const double eps = 1e-10;
const int N = 3e5 + 5;
const int M = 3e5;
typedef pair<double, int> PIII;

namespace Shab_Li_Chao_SegmentTree {
	int cmp(double x, double y) {
		if(x - y > eps) return 1;
		if(y - x > eps) return -1;
		return 0;
	}

	struct line {
		double k, b;
#define k(i) P[i].k
#define b(i) P[i].b
	} P[N];

	int s[N], cnt;
	
	void init() {
		int p = ++cnt;
		k(p) = 0, b(p) = -1000000000000;
	}

	double calc(int p, int d) {
		return b(p) + k(p) * d;
	}

	void Add(double x0, double y0, double x1, double y1) {
		int p = ++cnt;
		if(x0 == x1) k(p) = 0, b(p) = max(y0, y1);
		else k(p) = 1.0 * (y1 - y0) / (x1 - x0), b(p) = y0 - k(p) * x0;
	}

	void Upd(int p, int l, int r, int u) {
		int &v = s[p], mid = l + r >> 1;
		int bmid = cmp(calc(u, mid), calc(v, mid));
		if (bmid == 1 || (!bmid && u < v)) swap(u, v);
		int bl = cmp(calc(u, l), calc(v, l)), br = cmp(calc(u, r), calc(v, r));
		if (bl == 1 || (!bl && u < v)) Upd(p << 1, l, mid, u);
		if (br == 1 || (!br && u < v)) Upd(p << 1 | 1, mid + 1, r, u);
	}

	void update(int p, int ql, int qr, int l, int r, int u) {
		if (l <= ql && qr <= r) {
			Upd(p, ql, qr, u);
			return;
		}
		int mid = ql + qr >> 1;
		if (l <= mid) update(p << 1, ql, mid, l, r, u);
		if (mid < r) update(p << 1 | 1, mid + 1, qr, l, r, u);
	}

	PIII pmx(PIII x, PIII y) {
		if (cmp(x.first, y.first) == -1)
			return y;
		if (cmp(x.first, y.first) == 1)
			return x;
		return x.second < y.second ? x : y;
	}

	PIII query(int p, int l, int r, int d) {
		if (r < d || d < l) return {0, 0};
		int mid = l + r >> 1;
		double res = calc(s[p], d);
		if (l == r) return {res, s[p]};
		return pmx({res, s[p]}, pmx(query(p << 1, l, mid, d),
		                            query(p << 1 | 1, mid + 1, r, d)));
	}
}

using namespace Shab_Li_Chao_SegmentTree;

namespace SegmentTree {
	struct node {
		int l, r, sum, add;
		
		#define l(p) t[p].l
		#define r(p) t[p].r
		#define sum(p) t[p].sum
		#define add(p) t[p].add
	} t[N << 2];
	
	void pushup(int p) {
		sum(p) = sum(ls) + sum(rs);
	}
	
	void pushdown(int p) {
		if(add(p)) {
			add(ls) += add(p), add(rs) += add(p);
			sum(ls) += (r(ls) - l(ls) + 1) * add(p), sum(rs) += (r(rs) - l(rs) + 1) * add(p);
			add(p) = 0;
		}
	}
	
	void build(int p, int l, int r) {
		l(p) = l, r(p) = r;
		if(l == r) return;
		int mid = l + r >> 1; 
		build(ls, l, mid), build(rs, mid + 1, r);
		pushup(p);
	}
	
	void upd(int p, int l, int r, int x) {
		if(l <= l(p) && r(p) <= r) return sum(p) += (r(p) - l(p) + 1) * x, add(p) += x, void();
		pushdown(p);
		int mid = l(p) + r(p) >> 1;
		if(l <= mid) upd(ls, l, r, x);
		if(r > mid) upd(rs, l, r, x);
		pushup(p);
	}
	
	int ask(int p, int l, int r) {
		if(l <= l(p) && r(p) <= r) return sum(p);
		pushdown(p);
		int mid = l(p) + r(p) >> 1, val = 0;
		if(l <= mid) val += ask(ls, l, r);
		if(r > mid) val += ask(rs, l, r);
		return val;
	}
}

using namespace SegmentTree;



signed main() {
	ios::sync_with_stdio(0);
	cin.tie(nullptr), cout.tie(nullptr);
	
	int ans = 0, q, n;

	cin >> n >> q; 
	build(1, 1, n); init();
	
	while (q--) {
		int op;
		cin >> op;
		if (op == 1) {
			int u, v, a, b;
			cin >> u >> v >> a >> b;//a公差b首项 
			double k = a;
			double x0 = u, y0 = k * 1.0 * (x0 - u) + b, x1 = v, y1 = k * (x1 - u) + b;
			Add(x0, y0, x1, y1);
			update(1, 1, n, x0, x1, cnt);
		} else if(op == 3) {
			int x;
			cin >> x;
			int Q1 = query(1, 1, n, x).first,
				Q2 = ask(1, 1, x);
			if(!Q1) cout << "NA\n";
			else cout << Q1 + Q2 << '\n';
		} else {
			int u, v, a, b;
			cin >> u >> v >> a >> b;
			upd(1, u, u, b);
			if(u + 1 <= v) upd(1, u + 1, v, a);
			if(v + 1 <= n) upd(1, v + 1, v + 1, -(b + a * (v - u))); 
		}
		
	}
}
2024/7/15 11:49
加载中...