洛谷 P3391 文艺平衡树

题目描述

您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1

                --by洛谷

http://daniu.luogu.org/problem/show?pid=3391



裸的平衡树反转;

方法是按序列位置为关键字排序;

反转(l,r):

则将l-1置于根处,将r+1作为根的右儿子,这样,r+1的左子树就是需要反转的区间;

然后对r+1的左儿子,反转其左右儿子,并打上线段树一样的lazy标记,待以后反转她的子树;

一开始,企图把位置维护为关键字,然后排序;

这样,

若点A为父节点的左儿子,则key[A]=key[fa[A]]-size[rs[A]]-1;

若点A为父节点的右儿子,则key[A]=key[fa[A]]+size[ls[A]]+1;

然后查找直接按查询关键字的方法找,十分方便;

然而关键字是时时变化的,不好维护,

另一种方法是直接在初次建好树后就再也不考虑维护关键字的问题,

直接按第K大的方法搜索,(从某种意义上讲她早已不是一般意义上的查找树了)

怎么办,选哪种方法继续呢?

一个很好的方法是把两个都写出来,

反正差不多

多好啊,还能对拍,是吧

代码如下:

  1 #include<cstdio>
  2 using namespace std;
  3 int n,m;
  4 struct dt{
  5     int cnt,size,key,lz;
  6     int ch[2],fa;
  7 };
  8 struct Splay{
  9     int root,tot;
 10     dt data[100010];
 11     void in(){
 12         root=tot=0;
 13         data[0].fa=data[0].cnt=data[0].size=data[0].key=0;
 14     }
 15     void splay(int x,int end){
 16         int fa,fafa;
 17         for(fa=data[x].fa;(fa=data[x].fa)!=end;roll(x)){
 18             fafa=data[fa].fa;
 19             if(fafa!=end){
 20                 if((data[fafa].ch[1]==fa)^(data[fa].ch[1]==x))
 21                     roll(x);
 22                 else
 23                     roll(fa);
 24             }
 25         }
 26         if(!end)
 27             root=x;
 28     }
 29     void roll(int x){
 30         int fa=data[x].fa,fafa=data[fa].fa;
 31         int wh=data[fa].ch[1]==x;
 32         data[fa].ch[wh]=data[x].ch[wh^1];data[data[x].ch[wh^1]].fa=fa;
 33         data[x].ch[wh^1]=fa;data[fa].fa=x;
 34         if(fafa)
 35             data[fafa].ch[data[fafa].ch[1]==fa]=x;
 36         data[x].fa=fafa;
 37         up(fa);up(x);
 38     }
 39     void up(int x){
 40         data[x].size=data[data[x].ch[0]].size+data[data[x].ch[1]].size+1;
 41     }
 42     void buil_splay(int l,int r,int&nu,int fa){
 43         int mid=(l+r)>>1;
 44         nu=++tot;
 45         data[nu].key=mid;
 46         data[nu].fa=fa;
 47         data[nu].cnt=data[nu].size=1;
 48         if(l==r)return;
 49         if(l<mid)
 50             buil_splay(l,mid-1,data[nu].ch[0],nu);
 51         if(r>mid)
 52             buil_splay(mid+1,r,data[nu].ch[1],nu);
 53         data[nu].size=data[data[nu].ch[0]].size+data[data[nu].ch[1]].size+1;
 54     }
 55     int find(int x){
 56         int i=root;
 57         while(!(data[data[i].ch[0]].size<x&&x<=data[i].size-data[data[i].ch[1]].size)){
 58             if(data[i].lz){
 59                 change(data[i].ch[0]);
 60                 change(data[i].ch[1]);
 61                 data[i].lz=0;
 62             }
 63             if(x<=data[data[i].ch[0]].size)
 64                 i=data[i].ch[0];
 65             else{
 66                 x-=(data[i].size-data[data[i].ch[1]].size);
 67                 i=data[i].ch[1];
 68             }
 69         }
 70         if(data[i].lz){
 71             change(data[i].ch[0]);
 72             change(data[i].ch[1]);
 73             data[i].lz=0;
 74         }
 75         return i;
 76     }
 77     void change(int x){
 78         int fa=data[x].fa,i;
 79             i=data[x].ch[0];data[x].ch[0]=data[x].ch[1];data[x].ch[1]=i;
 80             data[x].lz^=1;
 81     }
 82     void print(int now){
 83         if(data[now].lz){
 84             change(data[now].ch[0]);
 85             change(data[now].ch[1]);
 86             data[now].lz=0;
 87         }
 88         if(data[now].ch[0])
 89             print(data[now].ch[0]);
 90         if(data[now].key!=0&&data[now].key!=n+1)
 91             printf("%d ",data[now].key);
 92         if(data[now].ch[1])
 93             print(data[now].ch[1]);
 94     }
 95 };
 96 Splay splay;
 97 int main()
 98 {
 99     int i,j,k,l;
100     scanf("%d%d",&n,&m);
101     splay.buil_splay(0,n+1,splay.root,0);
102     for(i=1;i<=m;i++){
103         scanf("%d%d",&j,&k);
104         if(j==k)continue;
105         l=splay.find(j);
106         splay.splay(l,0);
107         l=splay.find(k+2);
108         splay.splay(l,splay.root);
109         splay.change(splay.data[splay.data[splay.root].ch[1]].ch[0]);
110     }
111     splay.print(splay.root);
112 }
View Code

  

  1 #include<cstdio>
  2 using namespace std;
  3 int n,m;
  4 struct dt{
  5     int value,cnt,size,key,lz;
  6     int ch[2],fa;
  7 };
  8 struct Splay{
  9     int root,tot;
 10     dt data[100010];
 11     void in(){
 12         root=tot=0;
 13         data[0].fa=data[0].cnt=data[0].size=data[0].value=data[0].key=0;
 14     }
 15     void splay(int x,int end){
 16         int fa,fafa;
 17         for(fa=data[x].fa;(fa=data[x].fa)!=end;roll(x)){
 18             fafa=data[fa].fa;
 19             if(fafa!=end){
 20                 if((data[fafa].ch[1]==fa)^(data[fa].ch[1]==x))
 21                     roll(x);
 22                 else
 23                     roll(fa);
 24             }
 25         }
 26         if(!end)
 27             root=x;
 28     }
 29     void roll(int x){
 30         int fa=data[x].fa,fafa=data[fa].fa;
 31         int wh=data[fa].ch[1]==x;
 32         data[fa].ch[wh]=data[x].ch[wh^1];data[data[x].ch[wh^1]].fa=fa;
 33         data[x].ch[wh^1]=fa;data[fa].fa=x;
 34         if(fafa)
 35             data[fafa].ch[data[fafa].ch[1]==fa]=x;
 36         data[x].fa=fafa;
 37         up(fa);up(x);
 38     }
 39     void up(int x){
 40         data[x].size=data[data[x].ch[0]].size+data[data[x].ch[1]].size+1;
 41     }
 42     void buil_splay(int l,int r,int&nu,int fa){
 43         int mid=(l+r)>>1;
 44         nu=++tot;
 45         data[nu].value=data[nu].key=mid;
 46         data[nu].fa=fa;
 47         data[nu].cnt=data[nu].size=1;
 48         if(l==r)return;
 49         if(l<mid)
 50             buil_splay(l,mid-1,data[nu].ch[0],nu);
 51         if(r>mid)
 52             buil_splay(mid+1,r,data[nu].ch[1],nu);
 53         data[nu].size=data[data[nu].ch[0]].size+data[data[nu].ch[1]].size+1;
 54     }
 55     int find(int x){
 56         int i=root;
 57         while(1){
 58             change(data[i].ch[0]);
 59             change(data[i].ch[1]);
 60             data[i].lz=0;
 61             if(data[i].value==x)
 62                 break;
 63             i=data[i].ch[data[i].value<x];
 64         }
 65         return i;
 66     }
 67     void change(int x){
 68         int fa=data[x].fa,i;
 69         if(data[fa].lz){
 70                 i=data[x].ch[0];data[x].ch[0]=data[x].ch[1];data[x].ch[1]=i;
 71                 data[x].lz^=1;
 72             }
 73         if(data[fa].ch[0]==x)
 74             data[x].value=data[fa].value-data[data[x].ch[1]].size-1;
 75         else
 76             data[x].value=data[fa].value+data[data[x].ch[0]].size+1;
 77     }
 78     void print(int now){
 79         change(data[now].ch[0]);
 80         change(data[now].ch[1]);
 81         data[now].lz=0;
 82         if(data[now].ch[0])
 83             print(data[now].ch[0]);
 84         if(data[now].key!=0&&data[now].key!=n+1)
 85             printf("%d ",data[now].key);
 86         if(data[now].ch[1])
 87             print(data[now].ch[1]);
 88     }
 89 };
 90 Splay splay;
 91 int main()
 92 {
 93     int i,j,k,l;
 94     scanf("%d%d",&n,&m);
 95     splay.buil_splay(0,n+1,splay.root,0);
 96     for(i=1;i<=m;i++){
 97         scanf("%d%d",&j,&k);
 98         if(j==k)continue;
 99         l=splay.find(j-1);
100         splay.splay(l,0);
101         l=splay.find(k+1);
102         splay.splay(l,splay.root);
103         splay.data[splay.data[splay.root].ch[1]].lz=1;
104         splay.change(splay.data[splay.data[splay.root].ch[1]].ch[0]);
105         splay.data[splay.data[splay.root].ch[1]].lz=0;
106     }
107     splay.print(splay.root);
108 }
another_way

祝AC

 

转载于:https://www.cnblogs.com/nietzsche-oier/p/6670928.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/284013.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JSONObject中optString和getString等的区别

2019独角兽企业重金招聘Python工程师标准>>> 同事在看到我写的解析数据代码后&#xff0c;告诉我optString比getString好用&#xff0c;optString不会抛异常&#xff0c;而getString会抛异常&#xff0c;自己是将信将疑&#xff0c;就说&#xff0c;回去后我查查资料…

Lombok插件安装(IDEA)、配置jar包、使用

点击进入Lombok官网下载Lombok jar包 使用Lombok可能需要注意的地方 &#xff08;1&#xff09;当你的IDE是Idea时&#xff0c;要注意你的Idea是支持Lombok的&#xff0c;如果不支持请更换高版本尝试&#xff08;这里采用2018 3.3&#xff09;。 &#xff08;2&#xff09;在使…

Blazor University (40)JavaScript 互操作 —— 传递 HTML 元素引用

原文链接&#xff1a;https://blazor-university.com/javascript-interop/calling-javascript-from-dotnet/passing-html-element-references/传递 HTML 元素引用源代码[1]在编写 Blazor 应用程序时&#xff0c;不鼓励对文档对象模型 (DOM) 进行操作&#xff0c;因为它可能会干…

RabbitMQ+PHP 教程六(RPC)

(using php-amqplib) 前提必读 本教程假设RabbitMQ是安装在标准端口上运行&#xff08;5672&#xff09;。如果您使用不同的主机、端口或凭据&#xff0c;则连接设置需要调整。 如果您在本教程中遇到困难&#xff0c;可以通过邮件列表与我们联系。 开始 在第二个教程中&#xf…

TKMybatis 介绍和使用

目录 一、什么是 TKMybatis 二、TKMybatis 使用 2.1 Springboot 项目中加入依赖 2.2 使用讲解 2.2.1 实体类中使用 2.2.2 dao中使用 2.2.3 Service 层中使用 2.3 实际案例 2.3.1 dao 层使用 2.3.2 service 层使用 一、什么是 TKMybatis TKMybatis 是基于 Mybatis 框…

WinForm(三)揭开可视化控件的面纱

WinForm所见即所得的UI设计框架&#xff0c;开发效率确实有所提升&#xff0c;同时降低了编程门槛&#xff0c;让WinForm更普及。拖拖拽拽就能设计出一个界面&#xff0c;那么我们拖拽的这些东西是什么&#xff1f;它们是什么原理&#xff1f;。WinForm我觉得很好的一点是&…

RestTemplate 详解

在项目中&#xff0c;当我们需要远程调用一个 HTTP 接口时&#xff0c;我们经常会用到 RestTemplate 这个类。这个类是 Spring 框架提供的一个工具类。Spring 官网对它的介绍如下&#xff1a; RestTemplate: The original Spring REST client with a synchronous, template met…

初识Spark2.0之Spark SQL

内存计算平台Spark在今年6月份的时候正式发布了spark2.0&#xff0c;相比上一版本的spark1.6版本&#xff0c;在内存优化&#xff0c;数据组织&#xff0c;流计算等方面都做出了较大的改变&#xff0c;同时更加注重基于DataFrame数据组织的MLlib&#xff0c;更加注重机器学习整…

ABP详细教程——模块类

概述模块化是ABP vNext的最大亮点&#xff0c;也是ABP vNext框架的核心&#xff0c;而模块类是ABP vNext框架模块化的核心要素。这一章节&#xff0c;我就从模块类的用法、运行机制、源代码等层面&#xff0c;带大家详细了解ABP vNext的模块类。用法在ABP的约定中&#xff0c;每…

[转]Eureka工作原理

目录 Eureka 工作原理 Eureka 核心概念 自我保护机制 Eureka 集群原理 Eurka 工作流程 总结 Eureka 工作原理 上节内容为大家介绍了&#xff0c;注册中心 Eureka 产品的使用&#xff0c;以及如何利用 Eureka 搭建单台和集群的注册中心。这节课我们来继续学习 Eureka&…

重谈联想5G编码投票事件

此前&#xff0c;司马南谈了联想好几个问题&#xff0c;其中最尖锐的要属国有资产流失&#xff0c;这是联想管理层无法回避的死穴。不过&#xff0c;司马南批判联想5G投票背刺H公司&#xff0c;这基本就是造谣了。当年&#xff0c;媒体把编码投票炒作的很厉害&#xff0c;抨击联…

JStorm2.1.1集群的安装和使用

为什么80%的码农都做不了架构师&#xff1f;>>> JStorm2.1.1集群的安装和使用 Storm是一个免费开源、分布式、高容错的实时计算系统&#xff0c;而JStorm是阿里巴巴开源的基于Storm采用Java重写的一套分布式实时流计算框架&#xff0c;在性能和支持的集群规模上做了…

Hystrix 原理

Hystrix是什么&#xff1f; Hystrix是Netflix开源库&#xff0c;这是一个针对分布式系统的延迟和容错库。 Hystrix 供分布式系统使用&#xff0c;提供延迟和容错功能&#xff0c;隔离远程系统、访问和第三方程序库的访问点&#xff0c;防止级联失败&#xff0c;保证复杂的分布…

「深度」无人机实名制政策特稿|市场看好、资本关注,“反黑飞”正在崛起

从政策和需求来看&#xff0c;“反黑飞”越来越重要&#xff0c;市场也正在不断崛起。 对于大多数人来说&#xff0c;今天是最适合明目张胆“装嫩”的六一儿童节。不过&#xff0c;在无人机厂商和无人机玩家的眼里&#xff0c;今天是无人机实名制政策正式实施的日子。 近年来&…

在navicat中新建数据库

前言&#xff1a; 在本地新建一个名为editor的数据库&#xff1b; 过程&#xff1a; 1.&#xff1b; 2.选择&#xff1a;utf8mb4 -- UTF-8 Unicode字符集&#xff0c;原因在于&#xff1a;utf8mb4兼容utf8&#xff0c;且比utf8能表示更多的字符。&#xff0c;而且它支持表情符号…

MASA Stack 第三期社区例会

MASA Blazor 0.5.0发版内容功能Autocomplete&#xff1a;支持通过设置AutoSelectFirst参数开启自动选择第一项的功能&#xff0c;支持CacheItems参数&#xff0c;增强使用上下键的用户体验。BottomNavigation&#xff1a;&#xff1a;一个替代侧边栏的新组件。它主要用于移动应…

[转]高并发架构设计之--「服务降级」、「服务限流」与「服务熔断」

目录 服务降级 1 、简介 2 、使用场景 3 、核心设计 3.1 分布式开关 3.2 自动降级分类 3.3 配置中心 3.4 处理策略 3.5 降级分类 3.6 服务降级要考虑的问题 4 、高级特性 4.1 分级降级 4.2 降级权值 5 、总结与展望 服务限流 一、为什么要做服务限流设计&…

SpringBoot获取ApplicationContext

2019独角兽企业重金招聘Python工程师标准>>> 有两种方法&#xff1a; 创建Component实现ApplicationContextAware接口&#xff0c;SpringBoot会自动调用这个类的setApplicationConext()方法。鼓励使用这种方式。SpringApplication.run(MyApplication.class, args)这…

SkiaSharp 之 WPF 自绘 投篮小游戏(案例版)

此案例主要是针对光线投影法碰撞检测功能的示例&#xff0c;顺便做成了一个小游戏&#xff0c;很简单&#xff0c;但是&#xff0c;效果却很不错。投篮小游戏规则&#xff0c;点击投篮目标点&#xff0c;就会有一个球沿着相关抛物线&#xff0c;然后&#xff0c;判断是否进入篮…

zuul集成ribbon完成服务通信和负载均衡

目录 Zuul2服务通信 超时相关 默认超时配置 自定义超时配置 负载均衡 Zuul2服务通信 描述&#xff1a;zuul2通过Ribbon完成客户端负载均衡以及与服务器群集进行通信。 zuul2的通信是集成Ribbon实现的&#xff0c;在Origin中集成Ribbon基本配置&#xff08;例如IClientCo…