FHQ-Treap 求调 玄关
查看原帖
FHQ-Treap 求调 玄关
656427
iamsh楼主2025/1/21 16:40

全 WA,测试的时候发现输出的答案是随机的,有时候对有时候错,怀疑是最大子段和的维护有问题

#include<bits/stdc++.h>
using namespace std;
const int M = 114514;
class Treap {
	int root;
	struct node {
		int val,ls,rs,size,key;
		int lazy1,lazy2;//change,reverse
		int lsq,rsq,sum,sq;
		node() {
			val = ls = rs = size = 0;
			lazy1 = lazy2 = key = 0;
			lsq = rsq = sum = sq = 0;
		}
		node(int x) {
			val = x,size = 1,key = rand();
			lazy1 = M,lazy2 = ls = rs = 0;
			lsq = rsq = max(0,x);
			sum = sq = x;
		}
	};
	vector<node> tr;
	stack<int> del;
	#define lson tr[p].ls
	#define rson tr[p].rs
	private :
		int new_node(int val) {
			int rlt = 0;
			if(del.size()) {
				tr[del.top()] = node(val);
				rlt = del.top();
				del.pop();
			}
			else {
				tr.push_back(node(val));
				rlt = tr.size() - 1;
			}
			return rlt;
		}
		void update(int p) {
			node &t = tr[p],&l = tr[lson],&r = tr[rson];
			t.size = l.size + r.size + 1; 
			t.lsq = max(l.lsq,r.lsq + l.sum + t.val);
			t.rsq = max(r.rsq,l.rsq + r.sum + t.val);
			t.sum = l.sum + r.sum + t.val;
			t.sq = max({l.sq,r.sq,l.rsq + r.lsq + t.val});
		}
		void down(int p) {
			if(tr[p].lazy1 != M) {
				tr[lson].lazy1 = tr[rson].lazy1 = tr[p].lazy1;
				tr[p].val = tr[p].sum = tr[p].lazy1;
				tr[p].lazy1 = M;
			}
			if(tr[p].lazy2) {
				tr[lson].lazy2 ^= tr[p].lazy2;
				tr[rson].lazy2 ^= tr[p].lazy2;
				swap(lson,rson);
				tr[p].lazy2 = 0;
			}
		}
		void split(int p,int val,int &x,int &y) {
			if(!p) {
				x = y = 0;
				return ;
			}
			down(p);
			if(tr[lson].size + 1 <= val) {
				x = p,split(rson,val - tr[lson].size - 1,rson,y);
			}
			else {
				y = p,split(lson,val,x,lson);
			}
			update(p);
		}
		int merge(int x,int y) {
			if(!x || !y) {
				return x + y;
			}
			if(tr[x].key < tr[y].key) {
				down(x);
				tr[x].rs = merge(tr[x].rs,y);
				update(x);
				return x;
			}
			else {
				down(y);
				tr[y].ls = merge(x,tr[y].ls);
				update(y);
				return y;
			}
		}
		int merge(int x,int y,int z) {
			return merge(x,merge(y,z));
		}
	public :
		Treap() {
			root = 0;
			tr.push_back(node());
			srand(time(0));
		}
		void insert(int val) {
			int x,y;
			root = merge(root,new_node(val));
		}
		void insert(int t,vector<int> &val) {
			int x,y;
			split(root,t,x,y);
			for(int v : val) {
				x = merge(x,new_node(v));
			}
			root = merge(x,y);
		}
		void remove(int p) {
			if(!p) {
				return ;
			}
			del.push(p);
			remove(lson);
			remove(rson);
		}
		void erase(int l,int r) {
			int x,y,z;
			split(root,r,x,y);
			split(x,l - 1,x,z);
			remove(z);
			root = merge(x,y);
		}
		void change(int l,int r,int val) {
			int x,y,z;
			split(root,r,x,y);
			split(x,l - 1,x,z);
			tr[z].lazy1 = val;
			root = merge(x,z,y);
		}
		void reverse(int l,int r) {
			int x,y,z;
			split(root,r,x,y);
			split(x,l - 1,x,z);
			tr[z].lazy2 ^= 1;
			root = merge(x,z,y);
		}
		int query(int l,int r) {
			int x,y,z;
			split(root,r,x,y);
			split(x,l - 1,x,z);
			int ans = tr[z].sum;
			root = merge(x,z,y);
			return ans;
		}
		int max_sub() {
			return tr[root].sq;
		}
	#undef lson
	#undef rson
}T;
int main() {
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	int n,q;
	cin >> n >> q;
	while(n --) {
		int x;
		cin >> x;
		T.insert(x);
	}
	while(q --) {
		string op;
		cin >> op;
		if(op == "INSERT") {
			int x,y;
			vector<int> val;
			cin >> x >> y;
			while(y --) {
				int t;
				cin >> t;
				val.push_back(t);
			}
			T.insert(x,val);
		}
		else if(op == "DELETE") {
			int l,r;
			cin >> l >> r;
			r += l - 1;
			T.erase(l,r);
		}
		else if(op == "MAKE-SAME") {
			int l,r,val;
			cin >> l >> r >> val;
			r += l - 1;
			T.change(l,r,val);
		}
		else if(op == "REVERSE") {
			int l,r;
			cin >> l >> r;
			r += l - 1;
			T.reverse(l,r);
		}
		else if(op == "GET-SUM") {
			int l,r;
			cin >> l >> r;
			r += l - 1;
			cout << T.query(l,r) << "\n";
		}
		else {//MAX-SUM
			cout << T.max_sub() << "\n";
		}
	}
	return 0;
}
2025/1/21 16:40
加载中...