过阳历TLE 73pts站外题可爱线段树求条+悬关
  • 板块灌水区
  • 楼主tianyk
  • 当前回复17
  • 已保存回复17
  • 发布时间2024/10/16 15:02
  • 上次更新2024/10/16 18:47:07
查看原帖
过阳历TLE 73pts站外题可爱线段树求条+悬关
877101
tianyk楼主2024/10/16 15:02

题目传送门

#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5;

struct node {
	long long val, minn; //val生命值 minn生命非负最小值(若所有值都<0 则minn=-1)
	int cnt, die, sed; //cnt生命非负最小值数量 die死亡人数 sed(shield护盾)护盾数量
	friend node operator + (node a, node b) {
		node c;
		if (a.minn == b.minn) {
			if (a.minn >= 0) {
				c.minn = a.minn;
				c.cnt = a.cnt + b.cnt;
			} else
				c.minn = -1, c.cnt = 0;
		} else {
			if (a.minn > b.minn)
				swap(a, b);
			if (a.minn >= 0)
				c.minn = a.minn, c.cnt = a.cnt;
			else if (b.minn >= 0)
				c.minn = b.minn, c.cnt = b.cnt;
			else
				c.minn = -1, c.cnt = 0;
		}
		c.die = a.die + b.die;
		c.sed = a.sed + b.sed;
		return c;
	}
} tree[N << 2];
long long tag[N << 2], a[N];

void pushup(int rt) {
	tree[rt] = tree[rt << 1] + tree[rt << 1 | 1];
}

void build(int l, int r, int rt) {
	if (l == r) {
		tree[rt].val = tree[rt].minn = a[l];
		tree[rt].cnt = 1, tree[rt].sed = tree[rt].die = 0;
		return ;
	}
	int mid = l + r >> 1;
	build(l, mid, rt << 1);
	build(mid + 1, r, rt << 1 | 1);
	pushup(rt);
}

void pushdown(int l, int r, int rt) {
	if (tag[rt]) {
		tag[rt << 1] += tag[rt], tag[rt << 1 | 1] += tag[rt];
		tree[rt << 1].minn += tag[rt], tree[rt << 1 | 1].minn += tag[rt];
		tag[rt] = 0;
	}
}

void update1(int l, int r, int rt, int L, int R, int c) {//攻击
	if (tree[rt].die == r - l + 1)
		return ;
	int mid = l + r >> 1;
	if (L <= l && r <= R) {
		if (!tree[rt].sed) {
			if (tree[rt].minn >= -c) {
				tree[rt].minn += c;
				tag[rt] += c;
			} else {
				if (l == r) {
					tree[rt].val += c, tree[rt].minn = -1;
					tree[rt].cnt = tree[rt].sed = 0, tree[rt].die = 1;
				} else {
					pushdown(l, r, rt);
					if (L <= mid)
						update1(l, mid, rt << 1, L, R, c);
					if (R > mid)
						update1(mid + 1, r, rt << 1 | 1, L, R, c);
					pushup(rt);
				}
			}
		} else {
			if (l == r)
				tree[rt].sed--;
			else {
				pushdown(l, r, rt);
				if (L <= mid)
					update1(l, mid, rt << 1, L, R, c);
				if (R > mid)
					update1(mid + 1, r, rt << 1 | 1, L, R, c);
				pushup(rt);
			}
		}
		return ;
	}
	pushdown(l, r, rt);
	if (L <= mid)
		update1(l, mid, rt << 1, L, R, c);
	if (R > mid)
		update1(mid + 1, r, rt << 1 | 1, L, R, c);
	pushup(rt);
}

void update2(int l, int r, int rt, int L, int R, int c) {//治疗
	if (tree[rt].die == r - l + 1)
		return ;
	int mid = l + r >> 1;
	if (L <= l && r <= R) {
		if (!tree[rt].die) {
			tree[rt].minn += c;
			tag[rt] += c;
		} else {
			pushdown(l, r, rt);
			if (L <= mid)
				update2(l, mid, rt << 1, L, R, c);
			if (R > mid)
				update2(mid + 1, r, rt << 1 | 1, L, R, c);
			pushup(rt);
		}
		return ;
	}
	pushdown(l, r, rt);
	if (L <= mid)
		update2(l, mid, rt << 1, L, R, c);
	if (R > mid)
		update2(mid + 1, r, rt << 1 | 1, L, R, c);
	pushup(rt);
}

void update3(int l, int r, int rt, int p, int c) {//护盾
	if (l == r) {
		if (!tree[rt].die)
			tree[rt].sed++;
		return ;
	}
	pushdown(l, r, rt);
	int mid = l + r >> 1;
	if (p <= mid)
		update3(l, mid, rt << 1, p, c);
	if (p > mid)
		update3(mid + 1, r, rt << 1 | 1, p, c);
	pushup(rt);
}

node query(int l, int r, int rt, int L, int R) {
	if (L <= l && r <= R)
		return tree[rt];
	pushdown(l, r, rt);
	node ans;
	ans.minn = ans.val = -1;
	ans.cnt = ans.die = ans.sed = 0;
	int mid = l + r >> 1;
	if (L <= mid)
		ans = ans + query(l, mid, rt << 1, L, R);
	if (R > mid)
		ans = ans + query(mid + 1, r, rt << 1 | 1, L, R);
	return ans;
}

int main() {
	freopen("simulator.in", "r", stdin);
	freopen("simulator.out", "w", stdout);
	int n, q;
	scanf("%d", &n);
	for (int i = 1; i <= n; i++)
		scanf("%lld", &a[i]);
	scanf("%d", &q);
	build(1, n, 1);
	while (q--) {
		int pos, l, r;
		long long x;
		scanf("%d %d", &pos, &l);
		if (pos == 1) {
			scanf("%d %lld", &r, &x);
			update1(1, n, 1, l, r, -x);
		} else if (pos == 2) {
			scanf("%d %lld", &r, &x);
			update2(1, n, 1, l, r, x);
		} else if (pos == 3)
			update3(1, n, 1, l, 1);
		else if (pos == 4) {
			scanf("%d", &r);
			int ans = query(1, n, 1, l, r).die;
			printf("%d\n", ans);
		} else {
			scanf("%d", &r);
			node tmp = query(1, n, 1, l, r);
			int ans = 0;
			if (tmp.minn == 0)
				ans = tmp.cnt;
			printf("%d\n", ans);
		}
	}
	return 0;
}
2024/10/16 15:02
加载中...