bzoj3223 Tyvj 1729 文艺平衡树(Splay Tree+区间翻转)
2015-12-04 14:35
483 查看
3223: Tyvj 1729 文艺平衡树
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2202 Solved: 1226
[Submit][Status][Discuss]
Description
您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1Input
第一行为n,m n表示初始序列有n个数,这个序列依次是(1,2……n-1,n) m表示翻转操作次数接下来m行每行两个数[l,r] 数据保证 1<=l<=r<=n
Output
输出一行n个数字,表示原始序列经过m次变换后的结果Sample Input
5 31 3
1 3
1 4
Sample Output
4 3 2 1 5HINT
N,M<=100000【思路】
Splay Tree处理区间翻转。
分裂后打标记,然后合并即可。
【代码】
#include<cstdio> #include<vector> #include<cstring> #include<iostream> #define FOR(a,b,c) for(int a=(b);a<=(c);a++) using namespace std; const int maxn = 200000+10; struct Node{ Node* ch[2]; int v,s,flip; int cmp(int k) { int d=k-ch[0]->s; if(d==1) return -1; return d<=0? 0:1; } void maintain() { s=ch[0]->s+ch[1]->s+1; } void pushdown() { if(flip) { flip=0; swap(ch[0],ch[1]); ch[0]->flip^=1; ch[1]->flip^=1; } } }; Node* null=new Node(); 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(); int d=o->cmp(k); if(d==1) k-=o->ch[0]->s+1; if(d!=-1) { Node* p=o->ch[d]; p->pushdown(); int d2=p->cmp(k); int k2=d2==0? k:k-p->ch[0]->s-1; if(d2!=-1) { splay(p->ch[d2],k2); if(d==d2) rotate(o,d^1); else rotate(o->ch[d],d); } rotate(o,d^1); } } Node* merge(Node* left,Node* right) { splay(left,left->s); left->ch[1]=right,left->maintain(); return left; } void split(Node* o,int k,Node* &left,Node* &right) { splay(o,k); left=o,right=left->ch[1],left->ch[1]=null; left->maintain(); } struct SplaySequence { int n; Node seq[maxn]; Node* root; Node* build(int sz) { if(!sz) return null; Node* l=build(sz/2); Node* o=&seq[++n]; o->v=n; o->ch[0]=l; o->ch[1]=build(sz-sz/2-1); o->flip=o->s=0; o->maintain(); return o; } void init(int sz) { n=null->s=0; root=build(sz); } }spaly; vector<int> ans; void print(Node* o) { if(o!=null) { o->pushdown(); print(o->ch[0]); ans.push_back(o->v); print(o->ch[1]); } } int read() { char c=getchar(); while(!isdigit(c)) c=getchar(); int x=0; while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); } return x; } int n,m; int main() { n=read(),m=read(); spaly.init(n+1); //在开始添加虚拟结点 int l,r; Node *left,*right,*mid; while(m--) { l=read(),r=read(); split(spaly.root,l,left,right); split(right,r-l+1,mid,right); mid->flip^=1; spaly.root = merge(merge(left,mid),right); } print(spaly.root); for(int i=1;i<ans.size();i++) printf("%d ",ans[i]-1); return 0; }
PS:UVA 11922 Permutation Transformer 简化题目
相关文章推荐
- 【Codeforces Round 331 (Div 2)D】【DP 记忆化搜索 期望DP区间性质 好题】Wilbur and Trees 砍树随机从右从左概率左倒右倒的期望底面覆盖长度
- Centos6.7普通用户二进制安装mariadb10
- Linux服务器监控命令
- BeautifulSoap 安装和使用
- Android手势识别——上下左右滑动、屏幕上下左右中区域处理
- Java之美[从菜鸟到高手演变]系列
- OpenCV中使用神经网络 CvANN_MLP
- Zabbix 一个每天都有人在踩的坑!
- iOS 关于webView的使用方法
- android 监听网络连接状态的改变
- 数字证书原理
- 关于 dBm计算和换算问题
- mysql匿名用户引起的Access denied
- unity NGUI tutorial scroll view
- ASCII、Unicode、GBK和UTF-8字符编码的区别联系
- j++与++j
- android NFC 开发学习笔记(1)
- 关于WIN64+QT4.8.4+VS2008配置
- 常用的php数组函数
- online_judge_1014