为啥?
查看原帖
为啥?
676351
caoshuchen楼主2024/7/21 11:50

WA #3

已知是delSet的问题,而且是AC代码delSet的最后三行导致的正确。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll inf = 0x3f3f3f3f3f3f3f3f;

struct Value {
	long long sum, lmx, rmx, mx, len;
	Value(int x) {
		sum = x, len = 1;
		lmx = rmx = mx = x;
	}
	Value() {
		sum = len = 0;
		lmx = rmx = mx = ~inf;
	}
};
struct Tag {
	bool rev;
	ll a;
	Tag(int x, ll y) {
		rev = x % 2, a = y;
	}
	Tag() {
		rev = 0, a = ~inf;
	}
};
Value operator+(Value x, Value y) {
	Value ans;
	ans.sum = x.sum + y.sum;
	ans.len = x.len + y.len;
	ans.mx = max(max(x.mx, y.mx), x.rmx + y.lmx);
	ans.lmx = max(x.lmx, x.sum + y.lmx);
	ans.rmx = max(y.rmx, x.rmx + y.sum);
	return ans;
}
Tag operator*(Tag x, Tag y) {
	if (y.a != ~inf) {
		return Tag(0, y.a);
	}
	else if (x.a != ~inf) {
		return Tag(0, x.a);
	}
	else {
		return Tag(x.rev + y.rev, ~inf);
	}
}
Value operator*(Value x, Tag y) {
	Value ans;
	ans.len = x.len;
	if (y.a != ~inf) {
		ans.sum = y.a * x.len;
		ans.lmx = ans.rmx = ans.mx = (x.len != 0 ? max(y.a, ans.sum) : ~inf);
	}
	else if (y.rev) {
		ans.sum = x.sum;
		ans.lmx = x.rmx;
		ans.rmx = x.lmx;
		ans.mx = x.mx;
	}
	else
		ans = x;
	return ans;
}
Tag operator*=(Tag &x, Tag y) {
	return x = x * y;
}
Value operator*=(Value &x, Tag y) {
	return x = x * y;
}

struct Node {
	int l, r, p, sz, v;
	Value val;
	Tag tag;
	Node(int V, int pr) {
		v = V, val = Value(V), p = pr;
		tag = Tag(), l = r = 0, sz = 1;
	}
	Node() {
		l = r = p = sz = 0;
		val = Value(), tag = Tag();
	}
};

Node operator*(Node x, Tag y) {
	Node ans = x;
	ans.val = x.val * y;
	ans.tag = x.tag * y;
	if (y.rev)
		swap(ans.l, ans.r);
	if (y.a != ~inf)
		ans.v = y.a;
	return ans;
}

struct Splay {
	int n = 0, rt = 0, size = 0;
	vector<Node> a = vector<Node>(1100005, Node());
	stack<int> bin;
	void pushup(int x) {
		pushdown(x);
		a[x].sz = a[a[x].l].sz + 1 + a[a[x].r].sz;
		a[x].val = a[a[x].l].val + Value(a[x].v) + a[a[x].r].val;//中序遍历,这里没有交换律,要注意运算顺序 
	}
	void pushdown(int x) {
		a[a[x].l] = a[a[x].l] * a[x].tag;
		a[a[x].r] = a[a[x].r] * a[x].tag;
		a[x].tag = Tag();
	}
	void rotate(int x) {//旋一次 
		int p = a[x].p, g = a[a[x].p].p;
		if (x == a[p].l) {
			(a[g].l == p ? a[g].l : a[g].r) = x, a[x].p = g;
			a[p].l = a[x].r, a[a[x].r].p = p;
			a[x].r = p, a[p].p = x;
		}
		else {
			(a[g].l == p ? a[g].l : a[g].r) = x, a[x].p = g;
			a[p].r = a[x].l, a[a[x].l].p = p;
			a[x].l = p, a[p].p = x;
		}
		pushup(p), pushup(x);
	}
	void splay(int x, int tar) {//将x旋到tar的子节点 
		if (!tar)
			rt = x;
		while (true) {
			int p = a[x].p, g = a[a[x].p].p;
			if (p == tar)
				return ;
			if (g == tar) {
				rotate(x);
				return ;
			}
			if ((a[g].l == p) == (a[p].l == x))
				rotate(p), rotate(x);
			else
				rotate(x), rotate(x);
		}
	}
	int newNode() {
		if (bin.empty())
			return ++n;
		int x = bin.top();
		bin.pop();
		return x;
	}
	void insert(int &x, int pr, int v, int pos) {//在pos位置插入一个元素 
		if (x == 0) {
			size++;
			a[x = newNode()] = Node(v, pr);
			splay(x, 0);
			return ;
		}
		(pos <= a[a[x].l].sz + 1) ? insert(a[x].l, x, v, pos) : insert(a[x].r, x, v, pos - a[a[x].l].sz - 1);
	}
	int insert(int x, int pr, int l, int r, vector<int> &v) {//直接以x为跟建立,元素值为v中的[l,r] 
		if (l > r)
			return 0;
		int mid = (l + r) / 2;
		size++;
		a[x = newNode()] = Node(v[mid - 1], pr);
		int ls = insert(0, x, l, mid - 1, v);
		int rs = insert(0, x, mid + 1, r, v);
		a[x].l = ls, a[x].r = rs;
		pushup(x);
		return x;
	}
	void insertSet(vector<int> &v, int pos) {//在pos位置插入一组元素 
		if (size == 0) {
			rt = insert(0, 0, 1, v.size(), v);
			return ;
		}
		if (pos == 0) {
			int L1 = kth(rt, 1);
			splay(L1, 0);
			a[L1].l = insert(0, L1, 1, v.size(), v), pushup(L1);
			return ;
		}
		if (pos == size)  {
			int R1 = kth(rt, size);
			splay(R1, 0);
			a[R1].r = insert(0, R1, 1, v.size(), v), pushup(R1);
			return ;
		}
		int L1 = kth(rt, pos), R1 = kth(rt, pos + 1);
		splay(L1, 0), splay(R1, L1);
		a[R1].l = insert(0, R1, 1, v.size(), v), pushup(R1), pushup(L1);
	}
	int &GetPos(int L, int R) {
		if (L == 1 && R == size)
			return rt;
		if (R == size) {
			int L1 = kth(rt, L - 1);
			splay(L1, 0);
			return a[L1].r;
		}
		if (L == 1)  {
			int R1 = kth(rt, R + 1);
			splay(R1, 0);
			return a[R1].l;
		}
		int L1 = kth(rt, L - 1), R1 = kth(rt, R + 1);
		splay(L1, 0), splay(R1, L1);
		return a[R1].l;
	}
	void recyc(int x) {
		if (x == 0)
			return ;
		bin.push(x), size--;
		recyc(a[x].l), recyc(a[x].r);
	}
	void delSet(int L, int R) {
		int &x = GetPos(L, R);
		int p = a[x].p;
		recyc(x);
		x = 0;
		pushup(p);
		if (L != 1 && R != size)
			pushup(rt);
		return ;
	}
	Value qry(int L, int R) {
		int x = GetPos(L, R);
		return a[x].val;
	}
	void mdf(int L, int R, Tag v) {
		int x = GetPos(L, R);
		a[x] = a[x] * v;
		if (x != rt)
			line_pushup(x);
	}
	int kth(int x, int k) {//找序列第 k 个元素编号 
		pushdown(x);
		if (a[a[x].l].sz + 1 == k)
			return x;
		return (k <= a[a[x].l].sz) ? kth(a[x].l, k) : kth(a[x].r, k - a[a[x].l].sz - 1);
	}
	int rk(int x) {//求元素在序列中的位置 
		line_pushdown(x);
		splay(x, 0);
		return a[a[x].l].sz + 1;
	}
	void line_pushdown(int x) {//将元素x到根的路线pushdown一遍 
		if (x == 0)
			return ;
		line_pushdown(a[x].p);
		pushdown(x);
	}
	void line_pushup(int x) {//将元素x到根的路线pushup一遍 
		if (x == 0)
			return ;
		pushup(x);
		line_pushup(a[x].p);
	}
	void inOrd(int x) {//输出以x为根的子树的中序遍历 
		if (x == 0)
			return ;
		pushup(x);
		inOrd(a[x].l);
		cout << a[x].v << " ";
		inOrd(a[x].r);
	}
	void change(int x, int y) {//把第x个元素提出来插到第y个元素((l,r]前移1格,l补空 或 [l,r) 后移1格,r补空) 
		if (x < y) {
			mdf(x, y, Tag(1, ~inf));
			mdf(x, y - 1, Tag(1, ~inf));
		}
		else if (x > y) {
			mdf(y, x, Tag(1, ~inf));
			mdf(y + 1, x, Tag(1, ~inf));
		}
	}
	
} t;

int n, m;

int main() {
	freopen("out.out", "w", stdout);
	cin >> n >> m;
	for (int i = 1, a; i <= n; i++) {
		cin >> a;
		t.insert(t.rt, 0, a, i);
	}
	string op;
	for (int i = 1, pos, tot, v, l, r; i <= m; i++) {
		cin >> op;
		if (op == "INSERT") {
			cin >> pos >> tot;
			vector<int> c;
			while (tot--) {
				int tmp;
				cin >> tmp;
				c.push_back(tmp);
			}
			t.insertSet(c, pos);
		}
		else if (op == "DELETE") {
			cin >> pos >> tot;
			t.delSet(pos, pos + tot - 1);
		}
		else if (op == "MAKE-SAME") {
			cin >> pos >> tot >> v;
			t.mdf(pos, pos + tot - 1, Tag(0, v));
		}
		else if (op == "REVERSE") {
			cin >> pos >> tot;
			t.mdf(pos, pos + tot - 1, Tag(1, ~inf));
		}
		else if (op == "GET-SUM") {
			cin >> pos >> tot;
			cout << t.qry(pos, pos + tot - 1).sum << endl;
		}
		else
			cout << t.qry(1, t.size).mx << endl;
	}
	return 0;
}

AC

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll inf = 0x3f3f3f3f3f3f3f3f;

struct Value {
	long long sum, lmx, rmx, mx, len;
	Value(int x) {
		sum = x, len = 1;
		lmx = rmx = mx = x;
	}
	Value() {
		sum = len = 0;
		lmx = rmx = mx = ~inf;
	}
};
struct Tag {
	bool rev;
	ll a;
	Tag(int x, ll y) {
		rev = x % 2, a = y;
	}
	Tag() {
		rev = 0, a = ~inf;
	}
};
Value operator+(Value x, Value y) {
	Value ans;
	ans.sum = x.sum + y.sum;
	ans.len = x.len + y.len;
	ans.mx = max(max(x.mx, y.mx), x.rmx + y.lmx);
	ans.lmx = max(x.lmx, x.sum + y.lmx);
	ans.rmx = max(y.rmx, x.rmx + y.sum);
	return ans;
}
Tag operator*(Tag x, Tag y) {
	if (y.a != ~inf) {
		return Tag(0, y.a);
	}
	else if (x.a != ~inf) {
		return Tag(0, x.a);
	}
	else {
		return Tag(x.rev + y.rev, ~inf);
	}
}
Value operator*(Value x, Tag y) {
	Value ans;
	ans.len = x.len;
	if (y.a != ~inf) {
		ans.sum = y.a * x.len;
		ans.lmx = ans.rmx = ans.mx = (x.len != 0 ? max(y.a, ans.sum) : ~inf);
	}
	else if (y.rev) {
		ans.sum = x.sum;
		ans.lmx = x.rmx;
		ans.rmx = x.lmx;
		ans.mx = x.mx;
	}
	else
		ans = x;
	return ans;
}
Tag operator*=(Tag &x, Tag y) {
	return x = x * y;
}
Value operator*=(Value &x, Tag y) {
	return x = x * y;
}

struct Node {
	int l, r, p, sz, v;
	Value val;
	Tag tag;
	Node(int V, int pr) {
		v = V, val = Value(V), p = pr;
		tag = Tag(), l = r = 0, sz = 1;
	}
	Node() {
		l = r = p = sz = 0;
		val = Value(), tag = Tag();
	}
};

Node operator*(Node x, Tag y) {
	Node ans = x;
	ans.val = x.val * y;
	ans.tag = x.tag * y;
	if (y.rev)
		swap(ans.l, ans.r);
	if (y.a != ~inf)
		ans.v = y.a;
	return ans;
}

struct Splay {
	int n = 0, rt = 0, size = 0;
	vector<Node> a = vector<Node>(1100005, Node());
	stack<int> bin;
	void pushup(int x) {
		pushdown(x);
		a[x].sz = a[a[x].l].sz + 1 + a[a[x].r].sz;
		a[x].val = a[a[x].l].val + Value(a[x].v) + a[a[x].r].val;//中序遍历,这里没有交换律,要注意运算顺序 
	}
	void pushdown(int x) {
		a[a[x].l] = a[a[x].l] * a[x].tag;
		a[a[x].r] = a[a[x].r] * a[x].tag;
		a[x].tag = Tag();
	}
	void rotate(int x) {//旋一次 
		int p = a[x].p, g = a[a[x].p].p;
		if (x == a[p].l) {
			(a[g].l == p ? a[g].l : a[g].r) = x, a[x].p = g;
			a[p].l = a[x].r, a[a[x].r].p = p;
			a[x].r = p, a[p].p = x;
		}
		else {
			(a[g].l == p ? a[g].l : a[g].r) = x, a[x].p = g;
			a[p].r = a[x].l, a[a[x].l].p = p;
			a[x].l = p, a[p].p = x;
		}
		pushup(p), pushup(x);
	}
	void splay(int x, int tar) {//将x旋到tar的子节点 
		if (!tar)
			rt = x;
		while (true) {
			int p = a[x].p, g = a[a[x].p].p;
			if (p == tar)
				return ;
			if (g == tar) {
				rotate(x);
				return ;
			}
			if ((a[g].l == p) == (a[p].l == x))
				rotate(p), rotate(x);
			else
				rotate(x), rotate(x);
		}
	}
	void insert(int &x, int pr, int v, int pos) {//在pos位置插入一个元素 
		if (x == 0) {
			size++;
			a[x = newNode()] = Node(v, pr);
			splay(x, 0);
			return ;
		}
		(pos <= a[a[x].l].sz + 1) ? insert(a[x].l, x, v, pos) : insert(a[x].r, x, v, pos - a[a[x].l].sz - 1);
	}
	int newNode() {
		if (bin.empty())
			return ++n;
		int x = bin.top();
		bin.pop();
		return x;
	}
	int insert(int x, int pr, int l, int r, vector<int> &v) {//直接以x为跟建立,元素值为v中的[l,r] 
		if (l > r)
			return 0;
		int mid = (l + r) / 2;
		size++;
		a[x = newNode()] = Node(v[mid - 1], pr);
		int ls = insert(0, x, l, mid - 1, v);
		int rs = insert(0, x, mid + 1, r, v);
		a[x].l = ls, a[x].r = rs;
		pushup(x);
		return x;
	}
	void insertSet(vector<int> &v, int pos) {//在pos位置插入一组元素 
		if (size == 0) {
			rt = insert(0, 0, 1, v.size(), v);
			return ;
		}
		if (pos == 0) {
			int L1 = kth(rt, 1);
			splay(L1, 0);
			a[L1].l = insert(0, L1, 1, v.size(), v), pushup(L1);
			return ;
		}
		if (pos == size)  {
			int R1 = kth(rt, size);
			splay(R1, 0);
			a[R1].r = insert(0, R1, 1, v.size(), v), pushup(R1);
			return ;
		}
		int L1 = kth(rt, pos), R1 = kth(rt, pos + 1);
		splay(L1, 0), splay(R1, L1);
		a[R1].l = insert(0, R1, 1, v.size(), v), pushup(R1), pushup(L1);
	}
	void recyc(int x) {
		if (x == 0)
			return ;
		bin.push(x), size--;
		recyc(a[x].l), recyc(a[x].r);
	}
	void delSet(int L, int R) {
		if (L == 1 && R == size) {
			recyc(rt), rt = 0;
			return ;
		}
		if (R == size) {
			int L1 = kth(rt, L - 1);
			splay(L1, 0);
			recyc(a[L1].r), a[L1].r = 0, pushup(L1);
			return ;
		}
		if (L == 1)  {
			int R1 = kth(rt, R + 1);
			splay(R1, 0);
			recyc(a[R1].l), a[R1].l = 0, pushup(R1);
			return ;
		}
		int L1 = kth(rt, L - 1), R1 = kth(rt, R + 1);
		splay(L1, 0), splay(R1, L1);
		recyc(a[R1].l), a[R1].l = 0, pushup(R1), pushup(L1);
	}
	Value qry(int L, int R) {
		if (L == 1 && R == size) {
			return a[rt].val;
		}
		if (R == size) {
			int L1 = kth(rt, L - 1);
			splay(L1, 0);
			return a[a[L1].r].val;
		}
		if (L == 1)  {
			int R1 = kth(rt, R + 1);
			splay(R1, 0);
			return a[a[R1].l].val;
		}
		int L1 = kth(rt, L - 1), R1 = kth(rt, R + 1);
		splay(L1, 0), splay(R1, L1);
		return a[a[R1].l].val;
	}
	void mdf(int L, int R, Tag v) {
		if (L == 1 && R == size) {
			a[rt] = a[rt] * v;
			return ;
		}
		if (R == size) {
			int L1 = kth(rt, L - 1);
			splay(L1, 0);
			a[a[L1].r] = a[a[L1].r] * v;
			line_pushup(a[L1].r);
			return ;
		}
		if (L == 1)  {
			int R1 = kth(rt, R + 1);
			splay(R1, 0);
			a[a[R1].l] = a[a[R1].l] * v;
			line_pushup(a[R1].l);
			return ;
		}
		int L1 = kth(rt, L - 1), R1 = kth(rt, R + 1);
		splay(L1, 0), splay(R1, L1);
		a[a[R1].l] = a[a[R1].l] * v;
		line_pushup(a[R1].l);
	}
	int kth(int x, int k) {//找序列第 k 个元素编号 
		pushdown(x);
		if (a[a[x].l].sz + 1 == k)
			return x;
		return (k <= a[a[x].l].sz) ? kth(a[x].l, k) : kth(a[x].r, k - a[a[x].l].sz - 1);
	}
	int rk(int x) {//求元素在序列中的位置 
		line_pushdown(x);
		splay(x, 0);
		return a[a[x].l].sz + 1;
	}
	void line_pushdown(int x) {//将元素x到根的路线pushdown一遍 
		if (x == 0)
			return ;
		line_pushdown(a[x].p);
		pushdown(x);
	}
	void line_pushup(int x) {//将元素x到根的路线pushup一遍 
		if (x == 0)
			return ;
		pushup(x);
		line_pushup(a[x].p);
	}
	void inOrd(int x) {//输出以x为根的子树的中序遍历 
		if (x == 0)
			return ;
		pushup(x);
		inOrd(a[x].l);
		cout << a[x].v << " ";
		inOrd(a[x].r);
	}
	void change(int x, int y) {//把第x个元素提出来插到第y个元素((l,r]前移1格,l补空 或 [l,r) 后移1格,r补空) 
		if (x < y) {
			mdf(x, y, Tag(1, ~inf));
			mdf(x, y - 1, Tag(1, ~inf));
		}
		else if (x > y) {
			mdf(y, x, Tag(1, ~inf));
			mdf(y + 1, x, Tag(1, ~inf));
		}
	}
	
} t;

int n, m;

int main() {
	cin >> n >> m;
	for (int i = 1, a; i <= n; i++) {
		cin >> a;
		t.insert(t.rt, 0, a, i);
	}
	string op;
	for (int i = 1, pos, tot, v, l, r; i <= m; i++) {
		cin >> op;
		if (op == "INSERT") {
			cin >> pos >> tot;
			vector<int> c;
			while (tot--) {
				int tmp;
				cin >> tmp;
				c.push_back(tmp);
			}
			t.insertSet(c, pos);
		}
		else if (op == "DELETE") {
			cin >> pos >> tot;
			t.delSet(pos, pos + tot - 1);
		}
		else if (op == "MAKE-SAME") {
			cin >> pos >> tot >> v;
			t.mdf(pos, pos + tot - 1, Tag(0, v));
		}
		else if (op == "REVERSE") {
			cin >> pos >> tot;
			t.mdf(pos, pos + tot - 1, Tag(1, ~inf));
		}
		else if (op == "GET-SUM") {
			cin >> pos >> tot;
			cout << t.qry(pos, pos + tot - 1).sum << endl;
		}
		else {
			cout << t.qry(1, t.size).mx << endl;
		}
	}
	return 0;
}
2024/7/21 11:50
加载中...