HDU_3487

题意:给出n和q,n代表1-n的序列,接下来q有两种操作,Cut a b c:表示把区间[a,b]截掉然后放在第c个数的后面,Flip a b 表示把区间[a,b]反转,经过一系列的q操作,最后输出操作后的序列:

分析:首先建立初始化的树结构之前,先给n设置个极限范围0和n+1,防止特殊情况下越界,如果反转[a,b],则先把第a-1个数放在根节点,把b+1结点的数放在根节点的右儿子下面,此时根节点的右儿子的左儿子为根的子树就是[a,b]区间,然后把反转标记传递给该子树的根节点,如果剪切区间[a,b]则把第c+1个数旋转到根节点处,然后把根节点的右儿子为子树的最左面的节点旋转到该子树的根,此时把剪掉的子树的根节点连到根节点的右儿子的左儿子上面即可,需要注意的是,push_down和push_up的操作

codes:指针

  1. #include"stdio.h"
  2. #include"iostream"
  3. #include"queue"
  4. using namespace std;
  5. struct Link_cut
  6. {
  7.  
  8. queue<int>q;
  9. struct node //节点结构体
  10. {
  11. int key,val,son,flag;
  12. node *lson,*rson,*fa; //左儿子,右儿子,以及父节点
  13. node()
  14. {
  15. key=val=flag=;
  16. son=;
  17. lson=rson=fa=NULL;
  18. }
  19. };
  20. node *top,*root,*x,*y;
  21. void init() //建立根节点root的父节点top
  22. {
  23. top=new node();
  24. }
  25. int getNum(node *x) //以x为根的子树一共有多少个节点
  26. {
  27. if(x==NULL)return ;
  28. return x->son;
  29. }
  30. void push_up(node *rt)
  31. {
  32. rt->son=getNum(rt->lson)+getNum(rt->rson)+;
  33. }
  34. void push_down(node *rt)
  35. {
  36. if(rt==NULL)return;
  37. if(rt->flag)
  38. {
  39. rt->flag^=;
  40. Reversal(rt);
  41. if(rt->lson!=NULL)
  42. rt->lson->flag^=;
  43. if(rt->rson!=NULL)
  44. rt->rson->flag^=;
  45. }
  46. }
  47. void Rotate(node *x,int k) //k=0左旋k=1右旋
  48. {
  49. node *y=x->fa;
  50. if(k==)
  51. {
  52. y->rson=x->lson;
  53. if(y->rson!=NULL)
  54. y->rson->fa=y;
  55.  
  56. push_up(y);
  57. if(y->fa->rson==y)
  58. y->fa->rson=x;
  59. else
  60. y->fa->lson=x;
  61. x->fa=y->fa;
  62.  
  63. x->lson=y;
  64. y->fa=x;
  65. }
  66. else
  67. {
  68. y->lson=x->rson;
  69. if(y->lson!=NULL)
  70. y->lson->fa=y;
  71.  
  72. push_up(y);
  73. if(y->fa->lson==y)
  74. y->fa->lson=x;
  75. else
  76. y->fa->rson=x;
  77. x->fa=y->fa;
  78.  
  79. x->rson=y;
  80. y->fa=x;
  81. }
  82. }
  83. void Splay(node *x,node *f)//把x旋转到f的下面
  84. {
  85. while(x->fa!=f)
  86. {
  87. node *y=x->fa;
  88. node *z=y->fa;
  89. if(z==f)
  90. {
  91. if(y->rson==x)
  92. Rotate(x,);
  93. else
  94. Rotate(x,);
  95. }
  96. else
  97. {
  98. if(z->rson==y)
  99. {
  100. if(y->rson==x)
  101. {
  102. Rotate(y,);
  103. Rotate(x,);
  104. }
  105. else
  106. {
  107. Rotate(x,);
  108. Rotate(x,);
  109. }
  110. }
  111. else
  112. {
  113. if(y->lson==x)
  114. {
  115. Rotate(y,);
  116. Rotate(x,);
  117. }
  118. else
  119. {
  120. Rotate(x,);
  121. Rotate(x,);
  122. }
  123. }
  124. }
  125. }
  126. if(f==top)
  127. root=x;
  128. }
  129. void RotateTo(node *x,node *f)
  130. {
  131. Splay(x,f);
  132. push_up(x);
  133. }
  134. void RotateTo(int k,node *f)
  135. {
  136. node *x=root;
  137. k++;
  138. while()
  139. {
  140. push_down(x);
  141. int temp=getNum(x->lson)+;
  142. if(k==temp)break;
  143. if(k<temp)
  144. x=x->lson;
  145. else
  146. {
  147. k-=temp;
  148. x=x->rson;
  149. }
  150. }
  151. Splay(x,f);
  152. push_up(x);
  153. }
  154. void creatTree(int l,int r,int k,node *f) //初始化一颗二叉树
  155. {
  156. if(l>r)return;
  157. int mid=(l+r)/;
  158. node *rt=new node();
  159. if(f==top)
  160. root=rt;
  161. if(k==)
  162. {
  163. f->lson=rt;
  164. rt->fa=f;
  165. rt->key=mid;
  166. }
  167. else
  168. {
  169. f->rson=rt;
  170. rt->fa=f;
  171. rt->key=mid;
  172. }
  173. creatTree(l,mid-,,rt);
  174. creatTree(mid+,r,,rt);
  175. push_up(rt);
  176. }
  177. void Reversal(node *x)//交换x左右儿子的结点
  178. {
  179. if(x==NULL)return;
  180. node *y=x->lson;
  181. x->lson=x->rson;
  182. x->rson=y;
  183. }
  184. node *Find(int k) //找到第k的结点
  185. {
  186. node *x=root;
  187. k++;
  188. while()
  189. {
  190. push_down(x);
  191. int temp=getNum(x->lson)+;
  192. if(k==temp)break;
  193. else if(k<temp)
  194. x=x->lson;
  195. else
  196. {
  197. k-=temp;
  198. x=x->rson;
  199. }
  200. }
  201. return x;
  202. }
  203. node *FindRight(node *rt) //找到以rt为根节点的最右一个结点
  204. {
  205. node *x=rt;
  206. while()
  207. {
  208. push_down(x);
  209. if(x->rson==NULL)
  210. break;
  211. x=x->rson;
  212. }
  213. return x;
  214. }
  215. node *FindLeft(node *rt) //找到以rt为根节点的最左一个结点
  216. {
  217. node *x=rt;
  218. while()
  219. {
  220. push_down(x);
  221. if(x->lson==NULL)break;
  222. x=x->lson;
  223. }
  224. return x;
  225. }
  226. void Link(node *rt,int k) //把rt为根的子树连接到第k个结点的后面
  227. {
  228. root->rson->lson=NULL; //把区间砍掉
  229. node *x=Find(k);
  230. RotateTo(x,top);
  231. node *y=FindLeft(root->rson);
  232. RotateTo(y,root);
  233.  
  234. root->rson->lson=rt;
  235. rt->fa=root->rson;
  236. }
  237. void Output(node *x,int n)
  238. {
  239. if(x==NULL)return;
  240. push_down(x);
  241. Output(x->lson,n);
  242. if(x->key>=&&x->key<=n)
  243. q.push(x->key);
  244. Output(x->rson,n);
  245. }
  246. }h;
  247. int main()
  248. {
  249. int n,q;
  250. while(scanf("%d%d",&n,&q)!=-)
  251. {
  252. if(n==-&&q==-)break;
  253. h.init();
  254. h.creatTree(,n+,,h.top);
  255. char op[];
  256. int a,b,c;
  257.  
  258. while(q--)
  259. {
  260.  
  261. scanf("%s%d%d",op,&a,&b);
  262. if(op[]=='C')
  263. {
  264. scanf("%d",&c);
  265. h.RotateTo(a-,h.top);
  266. h.RotateTo(b+,h.root);
  267. h.Link(h.root->rson->lson,c);
  268. }
  269. else
  270. {
  271. h.RotateTo(a-,h.top);
  272. h.RotateTo(b+,h.root);
  273. h.root->rson->lson->flag^=;
  274. }
  275. }
  276. while(!h.q.empty())
  277. {
  278. h.q.pop();
  279. }
  280. h.Output(h.root,n);
  281. printf("%d",h.q.front());
  282. h.q.pop();
  283. while(!h.q.empty())
  284. {
  285. printf(" %d",h.q.front());
  286. h.q.pop();
  287. }
  288. puts("");
  289.  
  290. }
  291. }
  292. /*
  293. 8 1
  294. CUT 3 5 4
  295.  
  296. 5 1
  297. CUT 2 3 1
  298.  
  299. 8 3
  300. Cut 3 6 3
  301. Cut 2 6 2
  302. Cut 3 6 4
  303.  
  304. 8 1
  305. Flip 2 6
  306.  
  307. 10 5
  308. Cut 2 6 3
  309. Flip 4 9
  310. Flip 5 8
  311. Cut 6 7 3
  312. Flip 4 5
  313. */

codes:数组模拟

  1. #include"stdio.h"
  2. #include"iostream"
  3. #include"queue"
  4. #include"string.h"
  5. #define M 3000005
  6. using namespace std;
  7.  
  8. struct Text
  9. {
  10. int son[M][],fa[M],flip[M],num[M];
  11. int top;
  12. int root;
  13. vector<int>p;
  14. void init(int n)
  15. {
  16. top=n+;
  17. for(int i=;i<=n+;i++)
  18. {
  19. num[i]=;
  20. flip[i]=;
  21. son[i][]=son[i][]=-;
  22. fa[i]=-;
  23. }
  24. }
  25. void Rotate(int x,int k)
  26. {
  27. int y=fa[x];
  28. if(k==)
  29. {
  30. son[y][]=son[x][];
  31. if(son[y][]!=-)
  32. fa[son[y][]]=y;
  33.  
  34. push_up(y);
  35. if(son[fa[y]][]==y)
  36. son[fa[y]][]=x;
  37. else
  38. son[fa[y]][]=x;
  39. fa[x]=fa[y];
  40.  
  41. son[x][]=y;
  42. fa[y]=x;
  43. }
  44. else
  45. {
  46. son[y][]=son[x][];
  47. if(son[y][]!=-)
  48. fa[son[y][]]=y;
  49.  
  50. push_up(y);
  51. if(son[fa[y]][]==y)
  52. son[fa[y]][]=x;
  53. else
  54. son[fa[y]][]=x;
  55. fa[x]=fa[y];
  56.  
  57. son[x][]=y;
  58. fa[y]=x;
  59. }
  60. }
  61. int Find(int k)
  62. {
  63. k++;
  64. int x=root;
  65. while()
  66. {
  67. push_down(x);
  68. int temp=getNum(son[x][])+;
  69. if(temp==k)break;
  70. else if(k<temp)
  71. x=son[x][];
  72. else
  73. {
  74. k-=temp;
  75. x=son[x][];
  76. }
  77. }
  78. return x;
  79. }
  80. void splay(int x,int f)
  81. {
  82. if(x==-)return;
  83. while(fa[x]!=f)
  84. {
  85. int y=fa[x];
  86. int z=fa[y];
  87. if(z==f)
  88. {
  89. if(son[y][]==x)
  90. Rotate(x,);
  91. else
  92. Rotate(x,);
  93. }
  94. else
  95. {
  96. if(son[z][]==y)
  97. {
  98. if(son[y][]==x)
  99. {
  100. Rotate(y,);
  101. Rotate(x,);
  102. }
  103. else
  104. {
  105. Rotate(x,);
  106. Rotate(x,);
  107. }
  108. }
  109. else
  110. {
  111. if(son[y][]==x)
  112. {
  113. Rotate(y,);
  114. Rotate(x,);
  115. }
  116. else
  117. {
  118. Rotate(x,);
  119. Rotate(x,);
  120. }
  121. }
  122. }
  123. }
  124. if(f==top)
  125. root=x;
  126. }
  127. void RotateTo(int x,int f,int type)
  128. {
  129. if(!type)
  130. x=Find(x);
  131. splay(x,f);
  132. push_up(x);
  133. }
  134. void Reversal(int x)
  135. {
  136. if(x==-)return;
  137. int y=son[x][];
  138. son[x][]=son[x][];
  139. son[x][]=y;
  140. }
  141. void creat(int l,int r,int k,int f)
  142. {
  143. if(l>r)return;
  144. int mid=(l+r)/;
  145. if(f==top)
  146. root=mid;
  147. son[f][k]=mid;
  148. fa[mid]=f;
  149. creat(l,mid-,,mid);
  150. creat(mid+,r,,mid);
  151. push_up(mid);
  152. }
  153. int getNum(int x)
  154. {
  155. if(x==-)return ;
  156. return num[x];
  157. }
  158. void push_up(int rt)
  159. {
  160. num[rt]=getNum(son[rt][])+getNum(son[rt][])+;
  161. }
  162. void push_down(int rt)
  163. {
  164. if(rt==-)return;
  165. if(flip[rt])
  166. {
  167. flip[rt]^=;
  168. Reversal(rt);
  169. if(son[rt][]!=-)
  170. flip[son[rt][]]^=;
  171. if(son[rt][]!=-)
  172. flip[son[rt][]]^=;
  173. }
  174. }
  175. int findLeft(int rt)
  176. {
  177. int x=rt;
  178. while()
  179. {
  180. push_down(x);
  181. if(son[x][]==-)break;
  182. x=son[x][];
  183. }
  184. return x;
  185. }
  186. void CUT(int a,int b,int c)
  187. {
  188. RotateTo(a-,top,);
  189. RotateTo(b+,root,);
  190. int rt=son[son[root][]][];
  191. son[son[root][]][]=-;
  192.  
  193. RotateTo(c,top,);
  194. int x=findLeft(son[root][]);
  195. RotateTo(x,root,);
  196. son[son[root][]][]=rt;
  197. fa[rt]=son[root][];
  198. }
  199. void FLIP(int a,int b)
  200. {
  201. RotateTo(a-,top,);
  202. RotateTo(b+,root,);
  203. int x=son[son[root][]][];
  204. flip[x]^=;
  205. }
  206. void dfs(int rt,int n)
  207. {
  208. if(rt==-)return;
  209. push_down(rt);
  210. dfs(son[rt][],n);
  211. if(rt>=&&rt<=n)
  212. p.push_back(rt);
  213. dfs(son[rt][],n);
  214.  
  215. }
  216. void Output(int n)
  217. {
  218. dfs(root,n);
  219. printf("%d",p[]);
  220. for(int i=;i<(int)p.size();i++)
  221. printf(" %d",p[i]);
  222. puts("");
  223. p.clear();
  224. }
  225. }text;
  226. int main()
  227. {
  228. int n,q;
  229. while(scanf("%d%d",&n,&q)!=-)
  230. {
  231. if(n==q&&n==-)break;
  232. text.init(n);
  233. text.creat(,n+,,text.top);
  234. int a,b,c;
  235. char op[];
  236.  
  237. while(q--)
  238. {
  239. scanf("%s%d%d",op,&a,&b);
  240. if(op[]=='C')
  241. {
  242. scanf("%d",&c);
  243. text.CUT(a,b,c);
  244. }
  245. else
  246. text.FLIP(a,b);
  247.  
  248. }
  249. text.Output(n);
  250.  
  251. }
  252. return ;
  253. }
  254.  
  255. /*
  256. 10 5
  257. Cut 2 6 3
  258. Flip 4 9
  259. Flip 5 8
  260. Cut 6 7 3
  261. Flip 4 5
  262.  
  263. 10 5
  264. Flip 4 9
  265. Flip 5 8
  266. Cut 6 7 3
  267. Flip 4 5
  268.  
  269. 10 1
  270. Flip 2 9
  271. */
 

Hdu-3487 Splay树,删除,添加,Lazy延迟标记操作的更多相关文章

  1. hdu 3436 splay树+离散化*

    Queue-jumpers Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) To ...

  2. HDU 3487 Splay

    给定两种操作,一种是把一个数列的某一段切下来插到剩余数列的某一个位置上. 一种是翻转操作,把数列的某一段进行翻转. 都是Splay的基本操作.标准的Rotateto调整出 [a,b]区间.然后对[a, ...

  3. 题解报告:hdu 1698 Just a Hook(线段树区间修改+lazy懒标记的运用)

    Problem Description In the game of DotA, Pudge’s meat hook is actually the most horrible thing for m ...

  4. hdu 1890 splay树

    Robotic Sort Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tot ...

  5. HDU 4391 Paint The Wall(分块+延迟标记)

    Paint The Wall Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  6. 题解报告:poj 3468 A Simple Problem with Integers(线段树区间修改+lazy懒标记or树状数组)

    Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. On ...

  7. [线段树系列] LCT打延迟标记的正确姿势

    这一篇博客将教你什么? 如何用LCT打延迟标记,LCT和线段树延迟标记间的关系,为什么延迟标记要这样打. ——正片开始—— 学习这一篇博客前,确保你会以下知识: Link-Cut-Tree,普通线段树 ...

  8. Chip Factory HDU - 5536 字典树(删除节点|增加节点)

    题意: t组样例,对于每一组样例第一行输入一个n,下面在输入n个数 你需要从这n个数里面找出来三个数(设为x,y,z),找出来(x+y)^z(同样也可以(y+z)^1)的最大值 ("^&qu ...

  9. HDU 3487 Splay tree

    Play with Chain Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)T ...

随机推荐

  1. asr,tts,vsr

    http://max.book118.com/html/2014/0814/9432056.shtm   ASR技术的基础主要是信号处理和概率模型. 信号处理技术 语音信号处理 谱分析   基于时间的 ...

  2. openssh-server 安装

    sudo apt-get update sudo apt-get install openssh-server 1:ssh-keygen -t rsa -f ~/.ssh/id_rsa 这里会提示输入 ...

  3. ViewModel命令ICommand对象定义

    如果定义如下 public ICommand ViewMenuItemCommand: 那么UI绑定,则无法执行代理方法 需如下定义 public ICommand ViewMenuItemComma ...

  4. 【转】Android的材料设计兼容库(Design Support Library)

    转自:http://www.jcodecraeer.com/a/anzhuokaifa/developer/2015/0531/2958.html?mType=Group Android的材料设计兼容 ...

  5. iOS工程如何支持64-bit

    苹果在2014年10月20号发布了一条消息:从明年的二月一号开始,提交到App Store的应用必须支持64-bit.详细消息地址为:https://developer.apple.com/news/ ...

  6. php 或js 常用的正则表达式

    1.    平时做网站经常要用正则表达式,下面是一些讲解和例子,仅供大家参考和修改使用:2.    "^\d+$" //非负整数(正整数 + 0)3.    "^[0-9 ...

  7. ps、grep和kill联合使用杀掉进程(转)

    例如要杀掉hello这个进程,使用下面这个命令就能直接实现.   ps -ef |grep hello |awk '{print $2}'|xargs kill -9 这里是输出ps -ef |gre ...

  8. shell脚本编程-使用结构化命令(if/else)(转)

    11.1 使用if-then语句 格式如下 if语句会执行if行定义的那个命令,如果该命令的退出状态码是0,则then部分的语句就会执行,其他值,则不会   1 2 3 4 if command th ...

  9. Java之Ajax技术

    ajax(asynchronouse javascript and xml) 异步的javascript 和 xml(现在常把xml换成json): ajax是2005年提出的,在2006,2007年 ...

  10. (copy) How to remote desktop a Fedora 19 from a Windows 7

    source: http://forums.fedoraforum.org/showthread.php?t=293665 Try xrdp or freerdpInstall xrdp or fre ...