您的位置:首页 > 其它

poj 3580 splay

2015-08-26 15:26 381 查看
维修数列的简化版,要求的操作还是挺多的,运行时间大概1s。

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

const int N = 100002;
int v
;
int n, m;

struct Node
{
Node * ch[2];
int rank;
int sz;
int val;
int minn;
int add;
int flip;

int cmp( int x ) const
{
if ( x == rank ) return -1;
return x < rank ? 0 : 1;
}

void pushdown()
{
if ( add )
{
if ( ch[0] != NULL )
{
ch[0]->val += add;
ch[0]->minn += add;
ch[0]->add += add;
}
if ( ch[1] != NULL )
{
ch[1]->val += add;
ch[1]->minn += add;
ch[1]->add += add;
}
add = 0;
}
if ( flip )
{
swap( ch[0], ch[1] );
flip = 0;
if ( ch[0] != NULL )
{
ch[0]->flip ^= 1;
}
if ( ch[1] != NULL )
{
ch[1]->flip ^= 1;
}
}
}

void maintain()
{
sz = rank = 1;
minn = val;
if ( ch[0] != NULL )
{
sz += ch[0]->sz;
rank += ch[0]->sz;
minn = min( minn, ch[0]->minn );
}
if ( ch[1] != NULL )
{
sz += ch[1]->sz;
minn = min( minn, ch[1]->minn );
}
}
} * root;

void rotate( Node * & o, int d )
{
Node * k = o->ch[d ^ 1];
o->ch[d ^ 1] = k->ch[d];
k->ch[d] = o;
o->maintain();
k->maintain();
o = k;
}

void splay( Node * & o, int k )
{
o->pushdown();
o->maintain();
int d = o->cmp(k);
if ( d != -1 )
{
if ( d == 1 ) k -= o->rank;
Node * p = o->ch[d];
p->pushdown();
p->maintain();
int d2 = p->cmp(k);
if ( d2 != -1 )
{
int k2 = ( d2 == 0 ? k : k - p->rank );
splay( p->ch[d2], k2 );
if ( d == d2 )
{
rotate( o, d ^ 1 );
}
else
{
rotate( o->ch[d], d );
}
}
rotate( o, d ^ 1 );
}
}

Node * build( int l, int r )
{
if ( l > r ) return NULL;
Node * o = new Node();
int mid = ( l + r ) >> 1;
o->sz = r - l + 1;
o->val = o->minn = v[mid];
o->rank = mid - l + 1;
o->ch[0] = build( l, mid - 1 );
o->ch[1] = build( mid + 1, r );
o->maintain();
return o;
}

void setRange( int l, int r )
{
splay( root, l );
splay( root->ch[1], r - l + 2 );
}

void add( int l, int r, int d )
{
setRange( l, r );
root->ch[1]->ch[0]->val += d;
root->ch[1]->ch[0]->minn += d;
root->ch[1]->ch[0]->add += d;
}

void reverse( int l, int r )
{
setRange( l, r );
root->ch[1]->ch[0]->flip ^= 1;
}

void revolve( int l, int r, int d )
{
reverse( l, r - d );
reverse( r - d + 1, r );
reverse( l, r );
}

void insert( int k, int vv )
{
k++;
splay( root, k );
splay( root->ch[1], 1 );
Node * & o = root->ch[1]->ch[0];
o = new Node();
o->sz = o->rank = 1;
o->val = o->minn = vv;
o->add = o->flip = 0;
root->ch[1]->maintain();
root->maintain();
}

void remove( int k )
{
splay( root, k );
splay( root->ch[1], 2 );
root->ch[1]->ch[0] = NULL;
root->ch[1]->maintain();
root->maintain();
}

inline int query( int l, int r )
{
setRange( l, r );
return root->ch[1]->ch[0]->minn;
}

int main ()
{
while ( scanf("%d", &n) != EOF )
{
for ( int i = 1; i <= n; i++ )
{
scanf("%d", v + i);
}
root = build( 0, n + 1 );
char cmd[11];
int a, b, c;
scanf("%d", &m);
while ( m-- )
{
scanf("%s", cmd);
if ( cmd[0] == 'A' )
{
scanf("%d%d%d", &a, &b, &c);
add( a, b, c );
}
else if ( cmd[0] == 'R' )
{
if ( cmd[3] == 'E' )
{
scanf("%d%d", &a, &b);
reverse( a, b );
}
else if ( cmd[3] == 'O' )
{
scanf("%d%d%d", &a, &b, &c);
c = c % ( b - a + 1 );
if ( !c ) continue;
revolve( a, b, c );
}
}
else if ( cmd[0] == 'I' )
{
scanf("%d%d", &a, &b);
insert( a, b );
}
else if ( cmd[0] == 'D' )
{
scanf("%d", &a);
remove(a);
}
else
{
scanf("%d%d", &a, &b);
printf("%d\n", query( a, b ));
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: