• _bzoj1500 [NOI2005]维修数列【真·Splay】


    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1500

    注意MAX-SUM的时候,不可以是空串。

    #include <cstdio>
    #include <algorithm>
    
    const int maxn = 500005;
    
    int n, m, top, a[maxn], posi, tot, cc;
    char opr[15];
    struct Node {
    	Node * ch[2];
    	Node * fa;
    	int key, sm, mxl, mxr, mxs, siz, c, mx;
    	char rev;
    	Node(void);
    	int getsm(void) {
    		return c == -666666? sm: c * siz;
    	}
    	int getmxl(void) {
    		if (c == -666666) {
    			return rev? mxr: mxl;
    		}
    		if (c > 0) {
    			return c * siz;
    		}
    		return 0;
    	}
    	int getmxr(void) {
    		if (c == -666666) {
    			return rev? mxl: mxr;
    		}
    		if (c > 0) {
    			return c * siz;
    		}
    		return 0;
    	}
    	int getmxs(void) {
    		if (c == -666666) {
    			return mxs;
    		}
    		if (c > 0) {
    			return c * siz;
    		}
    		return 0;
    	}
    	int getmx(void) {
    		return c == -666666? mx: c;
    	}
    } *nil, *root, *tnode;
    Node * stk[maxn];
    
    Node::Node(void) {
    	ch[0] = ch[1] = fa = nil;
    	key = sm = mxl = mxr = mxs = siz = rev = 0;
    	mx = c = -666666;
    }
    inline void pushup(Node * x) {
    	x->siz = x->ch[0]->siz + x->ch[1]->siz + 1;
    	x->sm = x->ch[0]->getsm() + x->ch[1]->getsm() + x->key;
    	x->mxl = std::max(x->ch[0]->getmxl(), x->ch[0]->getsm() + x->key + x->ch[1]->getmxl());
    	x->mxr = std::max(x->ch[1]->getmxr(), x->ch[1]->getsm() + x->key + x->ch[0]->getmxr());
    	x->mxs = std::max(x->ch[0]->getmxs(), x->ch[1]->getmxs());
    	x->mxs = std::max(x->mxs, x->ch[0]->getmxr() + x->key + x->ch[1]->getmxl());
    	x->mx = std::max(x->ch[0]->getmx(), x->ch[1]->getmx());
    	x->mx = std::max(x->mx, x->key);
    }
    inline void pushdown(Node * x) {
    	if (x->c != -666666) {
    		x->ch[0]->c = x->ch[1]->c = x->c;
    		x->key = x->c;
    		x->sm = x->c * x->siz;
    		if (x->c > 0) {
    			x->mxl = x->mxr = x->mxs = x->sm;
    		}
    		else {
    			x->mxl = x->mxr = x->mxs = 0;
    		}
    		x->c = -666666;
    	}
    	if (x->rev) {
    		x->rev = 0;
    		x->ch[0]->rev ^= 1;
    		x->ch[1]->rev ^= 1;
    		std::swap(x->ch[0], x->ch[1]);
    	}
    }
    inline void rotate(Node* x) {
    	Node *y = x->fa;
    	if (y == y->fa->ch[0]) {
    		y->fa->ch[0] = x;
    	}
    	else {
    		y->fa->ch[1] = x;
    	}
    	x->fa = y->fa;
    	int dir = x == y->ch[1];
    	y->ch[dir] = x->ch[dir ^ 1];
    	x->ch[dir ^ 1]->fa = y;
    	x->ch[dir ^ 1] = y;
    	y->fa = x;
    	pushup(y);
    	pushup(x);
    }
    inline void splay(Node * x, Node * rt) {
    	Node * p;
    	char flag1, flag2;
    	top = 0;
    	for (Node * i = x; i != rt; i = i->fa) {
    		stk[top++] = i;
    	}
    	for (int i = top - 1; ~i; --i) {
    		pushdown(stk[i]);
    	}
    	while (x->fa != rt) {
    		p = x->fa;
    		if (p->fa == rt) {
    			rotate(x);
    		}
    		else {
    			flag1 = p == p->fa->ch[1];
    			flag2 = x == p->ch[1];
    			if (flag1 ^ flag2) {
    				rotate(x);
    			}
    			else {
    				rotate(p);
    			}
    			rotate(x);
    		}
    	}
    	if (rt == nil) {
    		root = x;
    	}
    }
    inline void modify(int pos1, int pos2) {
    	Node * x = root;
    	pushdown(x);
    	while (pos1 != x->ch[0]->siz + 1) {
    		if (pos1 <= x->ch[0]->siz) {
    			x = x->ch[0];
    		}
    		else {
    			pos1 -= x->ch[0]->siz + 1;
    			x = x->ch[1];
    		}
    		pushdown(x);
    	}
    	splay(x, nil);
    	x = root;
    	pushdown(x);
    	while (pos2 != x->ch[0]->siz + 1) {
    		if (pos2 <= x->ch[0]->siz) {
    			x = x->ch[0];
    		}
    		else {
    			pos2 -= x->ch[0]->siz + 1;
    			x = x->ch[1];
    		}
    		pushdown(x);
    	}
    	splay(x, root);
    }
    inline Node* ist(int left, int right) {
    	if (left > right) {
    		return nil;
    	}
    	Node * rt = new Node, *t;
    	int mid = (left + right) >> 1;
    	rt->key = a[mid];
    	t = ist(left, mid - 1);
    	t->fa = rt;
    	rt->ch[0] = t;
    	t = ist(mid + 1, right);
    	t->fa = rt;
    	rt->ch[1] = t;
    	pushup(rt);
    	return rt;
    }
    void clear(Node * x) {
    	if (x == nil) {
    		return;
    	}
    	clear(x->ch[0]);
    	clear(x->ch[1]);
    	delete x;
    }
    
    int main(void) {
    	//freopen("in.txt", "r", stdin);
    	nil = new Node;
    	root = nil;
    	scanf("%d%d", &n, &m);
    	for (int i = 2; i <= n + 1; ++i) {
    		scanf("%d", a + i);
    	}
    	root = ist(1, n = n + 2);
    	while (m--) {
    		scanf("%s", opr);
    		if (opr[2] == 'S') {	// INSERT
    			scanf("%d%d", &posi, &tot);
    			n += tot;
    			++posi;
    			modify(posi, posi + 1);
    			for (int i = 1; i <= tot; ++i) {
    				scanf("%d", a + i);
    			}
    			tnode = ist(1, tot);
    			tnode->fa = root->ch[1];
    			root->ch[1]->ch[0] = tnode;
    			pushup(root->ch[1]);
    			pushup(root);
    		}
    		else if (opr[2] == 'L') {	// DELETE
    			scanf("%d%d", &posi, &tot);
    			n -= tot;
    			++posi;
    			modify(posi - 1, posi + tot);
    			clear(root->ch[1]->ch[0]);
    			root->ch[1]->ch[0] = nil;
    			pushup(root->ch[1]);
    			pushup(root);
    		}
    		else if (opr[2] == 'K') {	// MAKE-SAME
    			scanf("%d%d%d", &posi, &tot, &cc);
    			++posi;
    			modify(posi - 1, posi + tot);
    			root->ch[1]->ch[0]->c = cc;
    			pushup(root->ch[1]);
    			pushup(root);
    		}
    		else if (opr[2] == 'V') {	// REVERSE
    			scanf("%d%d", &posi, &tot);
    			++posi;
    			modify(posi - 1, posi + tot);
    			root->ch[1]->ch[0]->rev ^= 1;
    			pushup(root->ch[1]);
    			pushup(root);
    		}
    		else if (opr[2] == 'T') {	// GET-SUM
    			scanf("%d%d", &posi, &tot);
    			++posi;
    			modify(posi - 1, posi + tot);
    			printf("%d
    ", root->ch[1]->ch[0]->getsm());
    		}
    		else {	// MAX-SUM
    			modify(1, n);
    			printf("%d
    ", root->ch[1]->ch[0]->getmx() > 0? root->getmxs(): root->ch[1]->ch[0]->getmx());
    		}
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    作为一个新手程序员该如何成长?
    不同语言在函数内部定义函数
    展示出版社:写上URL地址对应函数、函数当中查询出所有的出版社、对象交给模板、循环对象拿出每条数据展示
    ORM对象关系映射:
    登录功能和数据库校验:
    登录功能的实现:
    项目那几步走:先配置setting路径文件、创建数据库、执行数据库迁移命令、配置mysql数据库信息、注册app、注释中间件、pymysql替换mysqldb-配置urls路由-继续视图函数-然后HTML页面展示-HTML里面导入css文件、models配置数据库表、
    计算输入的年份是否为闰年,并利用条件运算符输入“是”或者“不是”
    Oracle数据库基本概念理解(3)
    Oracle数据库基本概念理解(3)
  • 原文地址:https://www.cnblogs.com/ciao-sora/p/6155464.html
Copyright © 2020-2023  润新知