POJ 3580 splay

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

#define mxn 100020
#define ls ( p[i].ch[0] )
#define rs ( p[i].ch[1] )

struct node {
	int ch[2];
	int val, add, s, mi;
    bool flip;
	void set( int x ) {
		ch[0] = ch[1] = 0;
		val = x, s = 1;
		mi = x;
		add = flip = 0;
	}
}p[mxn*2];
int sz;
void down( int i ) {
	if( p[i].add ) {
		if( ls )
			p[ls].add += p[i].add, p[ls].val += p[i].add, p[ls].mi += p[i].add;
		if( rs )
			p[rs].add += p[i].add, p[rs].val += p[i].add, p[rs].mi += p[i].add;
		p[i].add = 0;
	}
	if( p[i].flip ) {
		swap( ls, rs );
		p[ls].flip ^= 1;
		p[rs].flip ^= 1;
		p[i].flip = 0;
	}
}
void mt( int i ) {
	p[i].s = 1, p[i].mi = p[i].val;
	if( ls )
		p[i].s += p[ls].s, p[i].mi = min( p[i].mi, p[ls].mi );
	if( rs )
		p[i].s += p[rs].s, p[i].mi = min( p[i].mi, p[rs].mi );
}
int cmp( int i, int k ) {
	if( ls )
		k -= p[ls].s;
	if( k == 1 )
		return -1;
	return k <= 0? 0: 1;
}
void rt( int &i, int d ) {
	int k = p[i].ch[d^1];
	p[i].ch[d^1] = p[k].ch[d];
	p[k].ch[d] = i;
	mt( i );
	mt( k );
	i = k;
}
void splay( int &i, int k ) {
	down( i );
	int d = cmp( i, k );
	if( d == 1 )
		if( ls )
			k -= p[ls].s + 1;
		else
			k --;
	if( ~d ) {
		int o = p[i].ch[d];
		down( o );
		int d2 = cmp( o, k );
		if( ~d2 ) {
			if( d2 == 1 ) 
				if( p[o].ch[0] )
					k -= p[p[o].ch[0]].s + 1;
				else
					k --;
			splay( p[o].ch[d2], k );
			if( d == d2 )
				rt( i, d ^ 1 );
			else
				rt( p[i].ch[d], d );
		}
		rt( i, d ^ 1 );
	}
}
void split( int i, int k, int &left, int &right ) {
	 splay( i, k );
	 left = i;
	 right = rs;
	 p[i].ch[1] = 0;
	 mt( i );
}
int merge( int i, int o ) {
	splay( i, p[i].s );
	p[i].ch[1] = o;
	mt( i );
	return i;
}
int creat( int x ) {
	++sz;
	p[sz].set( x );
	return sz;
}

int n, a[mxn], root;
int build( int ll, int rr ) {
	if( ll > rr )
		return 0;
	int md = ( ll + rr ) >> 1;
	int tmp = build( ll, md - 1 );
	int ret = creat( a[md] );
	p[ret].ch[0] = tmp;
	p[ret].ch[1] = build( md + 1, rr );
	mt( ret );
	return ret;
}
void read() {
	sz = 0;
	root = creat( -1 );
	for( int i = 1; i <= n; ++i )
		scanf( "%d", &a[i] );
	p[root].ch[1] = build( 1, n );
	mt( root );
}
int main() {
//	freopen( "tt.txt", "r", stdin );
	while( scanf( "%d", &n ) != EOF ) {
		read();
		scanf( "%d", &n );
		while( n-- ) {
			char s[10];
			int l, r, val;
			int left, right, mid;
			scanf( "%s", s );
			if( s[0] == 'A' ) {
				scanf( "%d%d%d", &l, &r, &val );
				split( root, l, left, mid );
				split( mid, r - l + 1, root, right );
				p[root].add += val;
				p[root].val += val;
				p[root].mi += val;
				root = merge( left, root );
				root = merge( root, right );
			}
			if( s[0] == 'R' && s[3] == 'E' ) {
				scanf( "%d%d", &l, &r );
				split( root, l, left, mid );
				split( mid, r - l + 1, root, right );
				p[root].flip ^= 1;
				root = merge( left, root );
				root = merge( root, right );
			}
			if( s[0] == 'R' && s[3] == 'O' ) {
				scanf( "%d%d%d", &l, &r, &val );
				int tmp;
				val %= ( r - l + 1 );
				if( !val )
					continue;
				split( root, l, left, mid );
				split( mid, r - l + 1, tmp, right );
				split( tmp, r - l + 1 - val, root, mid );
				root = merge( mid, root );
				root = merge( left, root );
				root = merge( root, right );
			}
			if( s[0] == 'I' ) {
				scanf( "%d%d", &l, &val );
				split( root, l + 1, left, right );
				mid = creat( val );
				root = merge( left, mid );
				root = merge( root, right );
			}
			if( s[0] == 'D' ) {
				scanf( "%d%d", &l, &val );
				split( root, l, left, right );
				split( right, 1, mid, root );
				root = merge( left, root );
			}
			if( s[0] == 'M' ) {
				scanf( "%d%d", &l, &r );
				split( root, l, left, mid );
				split( mid, r - l + 1, root, right );
				printf( "%d\n", p[root].mi );
				root = merge( left, root );
				root = merge( root, right );
			}
		}
	}
	return 0;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值