hdu3487 伸展树(区间搬移 区间旋转)
对于区间旋转使用lazy思想就能解决。然后对于区间搬移,先把a-1结点做根,b+1作为它的右孩子,这样ch[ch[root][1]][0]就是区间[a,b],现将他取出。
然后在将当前的树伸展,把c结点转到根,c+1作为它的右孩子,这样c+1结点的左孩子就是空的,直接将上次取出的作为c+1结点的做孩子即可。
- #include<queue>
- #include<stack>
- #include<cmath>
- #include<cstdio>
- #include<cstring>
- #include<iostream>
- #include<algorithm>
- #define INF 99999999
- #define ll __int64
- #define lson l,m,rt<<1
- #define rson m+1,r,rt<<1|1
- #define key_value ch[ch[root][1]][0]
- using namespace std;
- const int MAXN = *;
- int pre[MAXN],ch[MAXN][],siz[MAXN],key[MAXN],rev[MAXN],root,tot1;
- int n;
- void Treavel(int x)
- {
- if(x)
- {
- Treavel(ch[x][]);
- printf("结点%2d:左儿子 %2d 右儿子 %2d 父结点 %2d size=%2d key=%2d\n",x,ch[x][],ch[x][],pre[x],siz[x],key[x]);
- Treavel(ch[x][]);
- }
- }
- void debug()
- {
- printf("root:%d\n",root);
- Treavel(root);
- }
- void Newnode(int &rt,int pa,int k)
- {
- rt = ++tot1;
- pre[rt] = pa;
- siz[rt] = ;
- rev[rt] = ;
- key[rt] = k;
- ch[rt][] = ch[rt][] = ;
- }
- void pushup(int rt)
- {
- siz[rt] = siz[ch[rt][]] + siz[ch[rt][]] + ;
- }
- void pushdown(int rt)
- {
- if(rev[rt]){
- rev[ch[rt][]] ^= ;
- rev[ch[rt][]] ^= ;
- swap(ch[rt][],ch[rt][]);
- rev[rt] = ;
- }
- }
- void build(int &rt,int l,int r,int pa)
- {
- if(l > r)
- return ;
- int m = (l+r)/;
- Newnode(rt,pa,m);
- build(ch[rt][],l,m-,rt);
- build(ch[rt][],m+,r,rt);
- pushup(rt);
- }
- void Init()
- {
- tot1 = root = ;
- pre[root] = siz[root] = key[root] = rev[root] = ;
- ch[root][] = ch[root][] = ;
- Newnode(root,,-);
- Newnode(ch[root][],root,-);
- build(key_value,,n,ch[root][]);
- pushup(ch[root][]);
- pushup(root);
- }
- void Rotate(int rt,int kind)
- {
- int y = pre[rt];
- pushdown(y);
- pushdown(rt);
- ch[y][!kind] = ch[rt][kind];
- pre[ch[rt][kind]] = y;
- if(pre[y]){
- ch[pre[y]][ch[pre[y]][]==y] = rt;
- }
- pre[rt] = pre[y];
- ch[rt][kind] = y;
- pre[y] = rt;
- pushup(y);
- }
- void splay(int rt,int goal)
- {
- pushdown(rt);
- while(pre[rt] != goal)
- {
- if(pre[pre[rt]] == goal){
- pushdown(pre[rt]);
- pushdown(rt);
- Rotate(rt,ch[pre[rt]][]==rt);
- }
- else {
- pushdown(pre[pre[rt]]);
- pushdown(pre[rt]);
- pushdown(rt);
- int y = pre[rt];
- int kind = ch[pre[y]][]==y;
- if(ch[y][kind] == rt){
- Rotate(rt,!kind);
- Rotate(rt,kind);
- }
- else {
- Rotate(y,kind);
- Rotate(rt,kind);
- }
- }
- }
- if(goal == )
- root = rt;
- pushup(rt);
- }
- int Get_kth(int rt,int k)
- {
- pushdown(rt);
- int t = siz[ch[rt][]] + ;
- if(t == k)
- return rt;
- else if(t > k){
- return Get_kth(ch[rt][],k);
- }
- else {
- return Get_kth(ch[rt][],k-t);
- }
- pushup(rt);
- }
- void cut(int x,int y,int z)
- {
- splay(Get_kth(root,x),);
- splay(Get_kth(root,y+),root);
- //debug();
- int tmp = key_value;
- key_value = ;
- pushup(ch[root][]);
- pushup(root);
- splay(Get_kth(root,z+),);
- splay(Get_kth(root,z+),root);
- //debug();
- key_value = tmp;
- pre[tmp] = ch[root][];
- pushup(ch[root][]);
- pushup(root);
- //debug();
- }
- int flag;
- void display(int rt)
- {
- if(rt == )
- return ;
- pushdown(rt);
- display(ch[rt][]);
- if(!flag && rt != && rt != ){
- flag = ;
- printf("%d",key[rt]);
- }
- else if(rt != && rt != ){
- printf(" %d",key[rt]);
- }
- display(ch[rt][]);
- }
- int main()
- {
- int i,j,m;
- while(~scanf("%d%d",&n,&m),n!=-&&m!=-)
- {
- Init();
- char work[];
- while(m--)
- {
- scanf("%s",work);
- if(work[] == 'F'){
- int x,y;
- scanf("%d%d",&x,&y);
- splay(Get_kth(root,x),);
- splay(Get_kth(root,y+),root);
- rev[key_value] ^= ;
- //debug();
- }
- else {
- int x,y,z;
- scanf("%d%d%d",&x,&y,&z);
- cut(x,y,z);
- }
- }
- //debug();
- flag = ;
- display(root);
- cout<<endl;
- }
- }
hdu3487 伸展树(区间搬移 区间旋转)的更多相关文章
- poj3580 伸展树(区间翻转 区间搬移 删除结点 加入结点 成段更新)
好题.我做了很久,学了大牛们的区间搬移.主要的代码都有注释. #include<cstdio> #include<cstring> #include<iostream&g ...
- 伸展树splay之求区间极值
前言 这篇博客是根据我在打这道题的时候遇到的问题,来打的,有些细节可能考虑不到. 题目 在N(1<=N<=100000)个数A1-An组成的序列上进行M(1<=M<=10000 ...
- hdu1890 伸展树(区间反转)
对于大神来说这题是水题.我搞这题花了快2天. 伸展树的优点有什么,就是树不管你怎么旋转序列是不会改变得,并且你要使区间反转,只要把第k大的点转到根结点,那么它的左子树就是要交换的区间[l,r),然后交 ...
- POJ 3468 A Simple Problem with Integers (伸展树区间更新求和操作 , 模板)
伸展数最基本操作的模板,区间求和,区间更新.为了方便理解,特定附上一自己搞的搓图 这是样例中的数据输入后建成的树,其中的1,2是加入的边界顶点,数字代表节点编号,我们如果要对一段区间[l, r]进行操 ...
- [置顶] hdu 1890 伸展树区间翻转
题意: 给你n个数,每次先输出第i大的数的位置(如果有多个,选下标小的那个),然后每次将第i个位置到第i大的数所在位置之间的数进行翻转. 思路:输入的数组可能有多个相同的值,我们可以进行两次排序把数组 ...
- Splay伸展树入门(单点操作,区间维护)附例题模板
Pps:终于学会了伸展树的区间操作,做一个完整的总结,总结一下自己的伸展树的单点操作和区间维护,顺便给未来的自己总结复习用. splay是一种平衡树,[平均]操作复杂度O(nlogn).首先平衡树先是 ...
- hdu 1754 splay tree伸展树 初战(单点更新,区间属性查询)
题意:与区间查询点更新,点有20W个,询问区间的最大值.曾经用线段树,1000+ms,今天的伸展树,890没ms,差不多. 第一次学习伸展树,一共花了2个单位时间,感觉伸展树真很有用,也很好玩.现在只 ...
- POJ 3468 A Simple Problem with Integers(线段树 成段增减+区间求和)
A Simple Problem with Integers [题目链接]A Simple Problem with Integers [题目类型]线段树 成段增减+区间求和 &题解: 线段树 ...
- poj-----(2528)Mayor's posters(线段树区间更新及区间统计+离散化)
Mayor's posters Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 43507 Accepted: 12693 ...
随机推荐
- poj 1463 Strategic game DP
题目地址:http://poj.org/problem?id=1463 题目: Strategic game Time Limit: 2000MS Memory Limit: 10000K Tot ...
- javascript中的this应用
1. this作为全局变量2. 作为对象方法的调用3. 作为构造函数调用4. apply调用 this是Javascript语言的一个关键字.它代表函数运行时,自动生成的一个内部对象,只能在函数内部使 ...
- UVALive 6450 Social Advertising DFS解法
题意:一些人有朋友关系,在某个人的社交网站上投放广告可以被所有该人的直接朋友看到,问最小投放多少个广告使给出的人都看到广告.(n<=20) 解法:看到n的范围可以想到用二进制数表示每个人被覆盖与 ...
- 2014 Super Training #1 C Ice-sugar Gourd 模拟,扫描线
原题 HDU 3363 http://acm.hdu.edu.cn/showproblem.php?pid=3363 给你一个串,串中有H跟T两种字符,然后切任意刀,使得能把H跟T各自分为原来的一半. ...
- Unity3d+Jenkins 自动编译iOS、Android版本
1.在Unity3d中, 创建导出 iOS.Android 项目脚本 PerformBuild.cs ,放在Editor目录下(必须),如下: using UnityEditor; using Sys ...
- Unity3d 内置图形界面系统(Editor GUI)
一.说在前面的 1.unity内置的ui系统,无论是在性能的表现上.功能的强大性上.制作复杂ui的便捷性上,还是其它的一些方面都不如一些第三方的插件来的好,如:NGUI和DF-GUI(PS: 后者比前 ...
- Linux 安装oracle客户端
环境: CentOS release 6.4 (Final) 一.下载文件 1.首先要查看oracle版本,对应的SQL如下: select * from V$version ; 2.根据oracl ...
- Properties集合的练习
1.更改文件中的数据,特定键的值: 需求:我有一个文本文件(user.txt),我知道数据是键值对形式的,但是不知道内容是什么. 请写一个程序判断是否有"lisi"这样的键存在,如 ...
- user database的initial size和dbcc shrinkfile
之前我们讨论了dbcc shrinkfile改变tempdb initial size的情况.而用DBCC Shrinkfile去收缩一个user database,情况就比较简单了.让我们通过一些测 ...
- matlab批量合并txt文件
1: %% merge.m 2: %%%%Main程序%%%%%% 3: %%%%%% 4: %%%%%%本程序合并完各个子文件夹中的txt到主文件目录下,并且合并的文件以子文件夹名字命名 5: %% ...