hdu3487Play with Chain(splay)
简单的两种操作,一种删除某段区间,加在第I个点的后面,另一个是翻转区间。都是splay的简单操作。
悲剧一:pushdown时候忘记让lz=0
悲剧二:删除区间,加在某点之后的时候忘记修改其父亲节点。
#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stdlib.h>
#include<vector>
#include<cmath>
#include<queue>
#include<set>
using namespace std;
#define N 300010
#define LL long long
#define INF 0xfffffff
#define key_value ch[ch[root][1]][0]
const double eps = 1e-;
const double pi = acos(-1.0);
const double inf = ~0u>>;
using namespace std;
struct splay_tree
{
int pre[N],size[N];
int ch[N][];
int root,tot,num,tot1;
int key[N],lz[N];
void dfs(int x)
{
if(x)
{
dfs(ch[x][]);
printf("结点%2d:左儿子 %2d 右儿子 %2d 父结点 %2d size=%2d,key=%2d lz = %d\n",
x,ch[x][],ch[x][],pre[x],size[x],key[x],lz[x]);
dfs(ch[x][]);
}
}
void debug()
{
printf("root:%d\n",root);
dfs(root);
}
//以上用于debug*/
void newnode(int &x,int v,int fa)//新建一结点
{
x = ++tot;
ch[x][]=ch[x][] = ;
pre[x] = fa;
lz[x] = ;
size[x] = ;
key[x] = v;
}
void pushdown(int w)
{
if(lz[w])
{
int l = ch[w][],r = ch[w][];
swap(ch[w][],ch[w][]); lz[l]^=lz[w];
lz[r]^=lz[w];
lz[w] = ;
}
}
void pushup(int w)//由儿子更新其父亲
{
size[w] = size[ch[w][]]+size[ch[w][]]+;
//cout<<s[w][0]<<" "<<s[w][1]<<endl;
}
void rotate(int r,int kind)//旋转操作,根据kind进行左旋和右旋
{
int y = pre[r];
pushdown(y);
pushdown(r);
ch[y][!kind] = ch[r][kind];
pre[ch[r][kind]] = y;
if(pre[y])
{
ch[pre[y]][ch[pre[y]][]==y] = r;
}
pre[r] = pre[y];
ch[r][kind] = y;
pre[y] = r;
pushup(y);
pushup(r);
}
void splay(int r,int goal)//将r结点旋至goal下
{
pushdown(r);
while(pre[r]!=goal)
{
if(pre[pre[r]]==goal)
{
rotate(r,ch[pre[r]][]==r);
}
else
{
int y = pre[r];
int kind = (ch[pre[y]][]==y);
if(ch[y][kind]==r)
{
rotate(r,!kind);
rotate(r,kind);
}
else
{
rotate(y,kind);
rotate(r,kind);
}
}
}
pushup(r);
if(goal==) root = r;
}
int get_k(int k)//得到第k个的结点
{
int r = root;
pushdown(r);
while(size[ch[r][]]+!=k)
{
if(size[ch[r][]]>=k)
r = ch[r][];
else
{
k-=(size[ch[r][]]+);//根据左右结点的数量来确定第k个节点在哪里
r = ch[r][];
}
pushdown(r);
}
pushup(r);
return r;
}
void cut(int l,int r,int k)
{
splay(get_k(l),);
splay(get_k(r+),root);
pushdown(ch[root][]);
int nod = key_value;
ch[ch[root][]][] = ;
pre[nod] = ;
pushup(ch[root][]);
pushup(root);
//debug();
splay(get_k(k),);
splay(get_k(k+),root);
ch[ch[root][]][] = nod;
pre[nod] = ch[root][];
pushup(ch[root][]);
pushup(root);
// debug();
}
void filp(int l,int r)
{
//cout<<get_k(l)<<" "<<get_k(r+2)<<endl;
splay(get_k(l),);
splay(get_k(r+),root); //cout<<","<<endl;debug();
lz[key_value]^=;
//swap(ch[key_value][0],ch[key_value][1]);
pushup(ch[root][]);
pushup(root);
}
void work(int n)
{
int i;
for(i = ;i < n ;i++)
{
printf("%d ",key[get_k(i+)]);
}
printf("%d\n",key[get_k(n+)]);
//debug();
}
void build(int &x,int l,int r,int fa)
{
int m = (l+r)>>;
if(l>r) return ;
newnode(x,m,fa);
build(ch[x][],l,m-,x);
build(ch[x][],m+,r,x);
pushup(x);
}
void init(int o)
{
size[] = ch[][] = ch[][] = key[] = lz[] = ;
root = tot = ;
newnode(root,,);
newnode(ch[root][],,root);
build(ch[ch[root][]][],,o,ch[root][]);
size[root] = ;
pushup(ch[root][]);
pushup(root);
}
}SP;
int main()
{
int n,q;
while(scanf("%d%d",&n,&q)!=EOF)
{
if(n==-&&q==-) break;
SP.init(n);
while(q--)
{
char sq[];
int k,x,y;
scanf("%s",sq);
if(sq[]=='C')
{
scanf("%d%d%d",&x,&y,&k);
SP.cut(x,y,k+);
// SP.debug();
// SP.work(n);
}
else
{
//SP.debug();
scanf("%d%d",&x,&y);
SP.filp(x,y);
//SP.debug();
}
//SP.work(n);
}
SP.work(n);
}
return ;
}
hdu3487Play with Chain(splay)的更多相关文章
- HDU--3487 Play with Chain (Splay伸展树)
Play with Chain Problem Description YaoYao is fond of playing his chains. He has a chain containing ...
- Hdu3487-Play with Chain(伸展树分裂合并)
Problem Description YaoYao is fond of playing his chains. He has a chain containing n diamonds on it ...
- HDU 3487 Play with Chain | Splay
Play with Chain Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...
- HDU3487 Play With Chain [Splay]
题目传送门 题目描述 Problem Description YaoYao is fond of playing his chains. He has a chain containing n dia ...
- hdu3487Play with Chain
Play with Chain Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)T ...
- HDU-3487 Play with Chain Splay tee区间反转,移动
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3487 对于一个数列有两种操作:1.CUT a b c,先取出a-b区间的数,然后把它们放在取出后的第c ...
- 【HDU 3487】Play with Chain Splay
题意 给定$n$个数序列,每次两个操作,将区间$[L,R]$拼接到去掉区间后的第$c$个数后,或者翻转$[L,R]$ Splay区间操作模板,对于区间提取操作,将$L-1$ Splay到根,再将$R+ ...
- HDU3487 Play with Chain splay 区间反转
HDU3487 splay最核心的功能是将平衡树中的节点旋转到他的某个祖先的位置,并且维持平衡树的性质不变. 两个操作(数组实现) cut l,r, c把[l,r]剪下来放到剩下序列中第c个后面的位置 ...
- HDU 3487 Play with Chain(Splay)
题目大意 给一个数列,初始时为 1, 2, 3, ..., n,现在有两种共 m 个操作 操作1. CUT a b c 表示把数列中第 a 个到第 b 个从原数列中删除得到一个新数列,并将它添加到新数 ...
随机推荐
- docker中Ubuntu安装jdk1.8
1.在宿主系统下载所需要的jdk版本的gz文件 https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133 ...
- web安全字体
webfont解剖 Unicode字体可以包含数以千计字形 有四个字体格式: WOFF2, WOFF, EOT, TTF 一些字体格式需要使用GZIP压缩 一个web字体是字形的集合,且每个字形是一个 ...
- 谈谈javaScript
谈谈javaScript (杰我学习) 一. 什么是JavaScript 人们通常所说的JavaScript,其正式名称为ECMAScript.这个标准由ECMA组织发展和维护.ECMA ...
- 机器学习 : 高斯混合模型及EM算法
Mixtures of Gaussian 这一讲,我们讨论利用EM (Expectation-Maximization)做概率密度的估计.假设我们有一组训练样本x(1),x(2),...x(m),因为 ...
- oracle 左右链接
数据表的连接有: 1.内连接(自然连接): inner只有两个表相匹配的行才能在结果集中出现 2.外连接: 包括 (1)左外连接(左边的表不加限制) (2)右外连接(右边的表不加限制) (3)全外连接 ...
- P2383 狗哥玩木棒
题目背景 狗哥又趁着语文课干些无聊的事了... 题目描述 现给出一些木棒长度,那么狗哥能否用给出的木棒(木棒全用完)组成一个正方形呢? 输入输出格式 输入格式: 输入文件中的第一行是一个整数n表示测试 ...
- Mysql源码学习——Thread Manager
一.前言 上篇的Connection Manager中,曾提及对于一个新到来的Connection,服务器会创建一个新的线程来处理这个连接. 其实没那么简单,为了提高系统效率,减少频繁创建线程和中止线 ...
- Microsoft Speech SDK开发包 使用
下载开发包.我们首先从微软的官网上面下载开发包,下载地址如下: http://www.microsoft.com/en-us/download/details.aspx?id=10121我们主要下载三 ...
- MSSQL 调用 .net 代码
http://www.cnblogs.com/laozhao8/p/3398681.html 在SQL Server中调用.NET程序集 需求是这样的,我在.net程序里操作数据时将一些字段数据加 ...
- 解决 'chromedriver' executable needs to be in PATH.'报错
试了把chromedriver.exe放到chrome安装文件下,python安装文件下,然后把路径配到path里,均无用. 最后是修改函数调用得以解决: from selenium import w ...