洛谷 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.pswp.cn/news/284013.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/284013.shtml
英文地址,請注明出處:http://en.pswp.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 框…

angularjs的ng-repeat回調

首先html代碼是這樣的&#xff1a; <label>Name des Leiters:</label><select name"leaderID" id"selectLeaderID"><option ng-repeat"manager in managers" value"leader_id{{manager.id}}&leader_name{{manager…

sed和vim練習

1、刪除/etc/grub2.conf文件中所有以空白開頭的行行首的空白字符sed s^[[:space:]]\ /etc/grub2.conf2、刪除/etc/fstab文件中所有以#開頭&#xff0c;后面至少跟一個空白字符的行的行首的#和空白字符sed -n s^#[[:space:]]\p /etc/fstab3、在/root/install.log每一行行首增加#…

WinForm(三)揭開可視化控件的面紗

WinForm所見即所得的UI設計框架&#xff0c;開發效率確實有所提升&#xff0c;同時降低了編程門檻&#xff0c;讓WinForm更普及。拖拖拽拽就能設計出一個界面&#xff0c;那么我們拖拽的這些東西是什么&#xff1f;它們是什么原理&#xff1f;。WinForm我覺得很好的一點是&…

淺談 maxMemory , totalMemory , freeMemory 和 OOM 與 native Heap

作者&#xff1a;林冠宏 / 指尖下的幽靈 掘金&#xff1a;https://juejin.im/user/587f0dfe128fe100570ce2d8 博客&#xff1a;http://www.cnblogs.com/linguanh/ GitHub &#xff1a; https://github.com/af913337456/ 騰訊云專欄&#xff1a; https://cloud.tencent.com/deve…

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;更加注重機器學習整…

webpack開發Vue配置

一直以來使用webpack都是用的別人的配置&#xff0c;這幾天自己學習了一下。 項目地址&#xff1a;https://github.com/donghaohao... 新建整個工程 npm init安裝依賴&#xff0c;這里我們開發vue項目&#xff0c;npm install vue --save&#xff0c;然后是開發時的依賴npm ins…

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&…

centos7下別名(alias)的特殊用法

版權聲明&#xff1a;轉載請注明出處:http://blog.csdn.net/dajitui2024 https://blog.csdn.net/dajitui2024/article/details/79438200 參考&#xff1a;https://www.cyberciti.biz/faq/bash-bypass-alias-command-on-linux-macos-unix/ 正常情況下&#xff0c;定義過的別名&a…

解決WDCP3環境gbk網站編碼程序亂碼問題

因為默認WDCP V3版本環境編碼格式是UTF-8版本&#xff0c;如果我們程序采用的是GBK編碼肯定都會有亂碼問題。 我們到WDCP后臺&#xff0c;"網站管理"-"PHP設置"&#xff0c;看到上圖所示&#xff0c;準備直接在線編輯PHP.INI文件。 這里我們找到"defa…

重談聯想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;今天是無人機實名制政策正式實施的日子。 近年來&…