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; }
相关文章推荐
- Active Directory Tools For SharePoint
- 【Git 】$ ./gradlew idea 构建一个idea的项目
- leetcode 220
- js根据类名获取元素——自定义getElementsByClass()
- Android下拉上滑显示与隐藏Toolbar另一种实现
- 理解Linux系统负荷
- pointPolygonTest函数
- R语言_方差分析
- Android下拉上滑显示与隐藏Toolbar另一种实现
- salt-API基本验证命令
- JS文档生成工具:JSDoc 介绍
- Hibernate延迟加载
- Ext 拆线图 LiveAnimated
- AndroidManifest.xml
- nginx相关
- Swing 自定义日期选择器
- 【C++】模拟string类的实现(string 类的深拷贝)
- SharePoint PowerShell命令系列 (8) Remove-SPSite
- win10中通用应用中集成Cortana小娜探索
- JAVA利用HttpClient进行POST请求(HTTPS)