ZOJ 2112 Dynamic Rankings

這里是題目地址

?

其實就是帶修改的區間第K大。

寫了一下BIT套主席樹,內存飛起,似乎需要特別的優化技巧 = =?所以還是寫了一下線段樹套平衡樹,跑了1s左右。

其實線段樹套平衡樹就是歸并樹的自然擴展而已。

歸并樹是把歸并排序的過程建成一顆線段樹,每個節點是一個數組,存的是這個節點對應區間的元素的正序:

空間復雜度O( n log n ) 。

每次查詢的時候二分答案, 問題轉化成詢問區間中有多少個數比k小。外層查詢和一般的線段樹一樣,只是在線段樹的節點處需要再次二分得到節點區間中比k小的數的個數。這樣二分答案有一個log ,線段樹中詢問也需要一個log ,線段樹節點處二分需要一個log ,每次詢問的復雜度為O( log^3 n ) 。

?

加入修改操作的時候,只需要把線段樹節點的數組改為平衡樹實現就好了。這是很自然的,線段樹節點維護對應節點的順序,又要支持修改,顯然平衡樹符合要求。

平衡樹用splay實現了一下跑了1080ms ,然后用Treap實現了一下RE得渾身難受。。。實在是碼力不行啊Orz

  1 #include <iostream>
  2 #include <cstring>
  3 #include <cstdio>
  4 using namespace std ;
  5 const int N = 50000 +10 ,INF = ~1u>>1;
  6 int M ,num[N] ;
  7 struct node{
  8     node *ch[2] ,*p ;
  9     int size ,val ;
 10     bool d() ;
 11     void setc( node * ,bool ) ,rol() ,pushup() ;
 12 }pool[N*19] ,*cur ,NU ,*null = &NU ;
 13 bool node::d(){
 14     return p->ch[1] == this ;
 15 }
 16 void node::setc( node *c ,bool d ){
 17     ch[d] = c ,c->p = this ;
 18 }
 19 void node::rol(){
 20     node *s = p ;
 21     int dd = d() ;
 22     s->p->setc( this ,p->d() ) ;
 23     s->setc( ch[!dd] ,dd ) ;
 24     setc( s ,!dd ) ;
 25     s->pushup() ;
 26 }
 27 void node::pushup(){
 28     size = ch[0]->size + ch[1]->size + 1 ;
 29 }
 30 struct Splay{
 31     node *root ;
 32     void splay( node * ,node * ) ,insert( node * ) ;
 33     void change( int ,int ) ,find( int ) ,init() ;
 34     node *get( int ) ;
 35     int rank( int ) ;
 36 }tree[N<<2] ;
 37 
 38 node *newnode( int val ){
 39     cur->val = val ;
 40     cur->size = 1 ;
 41     cur->ch[0] = cur->ch[1] = cur->p = null ;
 42     return cur ++ ;
 43 }
 44 void Splay::init(){
 45     root = newnode(-INF) ;
 46 }
 47 void Splay::splay( node *x ,node *p = null ){
 48     while( x->p != p ){
 49         if( x->p->p != p )
 50             x->d() == x->p->d() ? x->p->rol() : x->rol() ;
 51         x->rol() ;
 52     }
 53     x->pushup() ;
 54     if( p == null ) root = x ;
 55 }
 56 void Splay::insert( node *x ){
 57     if( root == null ) root = x ,root->p = null ;
 58     else for( node *t = root ;; ){
 59         ++t->size ;
 60         node *&s = t->ch[ x->val > t->val ] ;
 61         if( s == null ){
 62             s = x ,s->p = t ;
 63             splay( x ) ;
 64             break ;
 65         }
 66         t = s ;
 67     }
 68 }
 69 void Splay::find( int x ){
 70     for( node *t = root ;; ){
 71         if( x == t->val ){
 72             splay( t ) ;
 73             return ;
 74         }
 75         t = t->ch[ x > t->val ] ;
 76     }
 77 }
 78 void Splay::change( int x ,int val ){
 79     find( x ) ;
 80     node *p = root ;
 81     node *t = get( root->ch[0]->size ) ;
 82     splay( t ,root ) ;
 83     t->setc( root->ch[1] ,1 ) ;
 84     t->pushup() ,root = t ,t->p = null ;
 85     p->val = val ,p->size = 1 ;
 86     p->ch[0] = p->ch[1] = null ;
 87     insert( p ) ;
 88     return ;
 89 }
 90 node *Splay::get( int s ){
 91     for( node *t = root ;; ){
 92         int k = t->ch[0]->size ;
 93         if( s == k + 1 ) return t ;
 94         if( s > k + 1 ) s -= k + 1 ,t = t->ch[1] ;
 95         else t = t->ch[0] ;
 96     }
 97 }
 98 int Splay::rank( int x ){
 99     int res = 0 ;
100     for( node *t = root ;; ){
101         node *&s = t->ch[ x > t->val ] ;
102         if( t->val < x ) res += t->ch[0]->size + 1 ;
103         if( s == null ){
104             splay(t) ;
105             return res - 1 ;
106         }
107         t = s ;
108     }
109 }
110 void setIt( int p ,int k ,int s = M ,int x = 1 ){
111     tree[x].insert( newnode(k) ) ;
112     if( s == 1 ) return ;
113     if( p <= s/2 ) setIt( p ,k ,s/2 ,x<<1 ) ;
114     else setIt( p - s/2 ,k ,s - s/2 ,x<<1|1 ) ;
115 }
116 void change( int p ,int u ,int v ,int s = M ,int x = 1 ){
117     tree[x].change( u ,v ) ;
118     if( s == 1 ) return ;
119     if( p <= s/2 ) change( p ,u ,v ,s/2 ,x<<1 ) ;
120     else change( p-s/2 ,u ,v ,s-s/2 ,x<<1|1 ) ;
121 }
122 int Q ;
123 void query( int l ,int r ,int ans ,int s = M ,int x = 1 ){
124     if( l <= 1 && r >= s ){
125         Q += tree[x].rank(ans) ;
126         return ;
127     }
128     if( l <= s/2 ) query( l ,r ,ans ,s/2 ,x<<1 ) ;
129     if( r > s/2 ) query( l-s/2 ,r-s/2 ,ans ,s-s/2 ,x<<1|1 ) ;
130 }
131 bool judge( int l ,int r ,int ans ,int kth ){
132     Q = 0 ;
133     query( l ,r ,ans ) ;
134     if( Q <= kth - 1 ) return 1;
135     return 0 ;
136 }
137 void init(){
138     cur = pool ;
139 }
140 void build( int x = 1 ,int s = M ){
141     tree[x].init() ;
142     if( s == 1 ) return ;
143     build( x<<1 ,s/2 ) ;
144     build( x<<1|1 ,s-s/2 ) ;
145 }
146 int main(){
147     int n ,m ,x ,s ,t ,u ;
148     int T ;
149     scanf( "%d" ,&T ) ;
150     while( T -- ){
151         scanf("%d %d" ,&n ,&m ) ;
152         M = n ;
153         init() ;
154         int minn = 0 ,maxn = 0 ;
155         build();
156         for( int i = 1 ;i <= n ;i ++ ){
157             scanf( "%d" ,&x ) ;
158             num[i] = x ;
159             setIt( i ,x ) ;
160             minn = min ( minn ,x ) ;
161             maxn = max ( maxn ,x ) ;
162         }
163         char o[2];
164         while( m -- ){
165             scanf( "%s" ,&o ) ;
166             if( o[0] == 'C' ){
167                 scanf( "%d %d" ,&s ,&t ) ;
168                 minn = min( minn ,t ) ;
169                 maxn = max( maxn ,t ) ;
170                 change( s ,num[s] ,t ) ;
171                 num[s] = t ;
172                 continue ;
173             }
174             scanf( "%d %d %d" ,&s ,&t ,&u ) ;
175             int l = minn ,r = maxn ;
176             while( l < r ){
177                 int mid = ( l + r >> 1 ) + 1 ;
178                 if( judge( s ,t ,mid ,u ) ) l = mid ;
179                 else r = mid - 1 ;
180             }
181             printf( "%d\n" ,l ) ;
182         }
183     }
184 }
CODE

?

轉載于:https://www.cnblogs.com/MyWither/p/3563779.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/273854.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/273854.shtml
英文地址,請注明出處:http://en.pswp.cn/news/273854.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

python3[進階]8.對象引用、可變性和垃圾回收

文章目錄8.1變量不是盒子8.2 標識,相等性和別名8.2.1 在和is之間選擇8.2.2 元組的相對不可變性8.3 默認做淺復制&#xff08;拓展&#xff09;為任意對象做深復制和淺復制深拷貝和淺拷貝有什么具體的區別呢&#xff1f;8.4 函數的參數作為引用時8.4.1 不要使用可變類型作為參數…

openfire修改服務器名稱方法

1.登陸openfire管理頁面&#xff0c;在主頁面下方選擇編輯屬性&#xff0c;修改服務器名稱為當前主機名稱&#xff0c;點擊保存屬性&#xff0c;按頁面提示重啟服務器。 2.重啟后&#xff0c;主頁的服務器屬性下的服務器名稱出現一個嘆號&#xff0c;鼠標放上去顯示Found RSA c…

python (第八章)補充-可迭代對象(補充高階函數,以及常用的高階函數)

文章目錄可迭代對象迭代器什么是迭代器什么是生成器生成器的作用生成器的注意事項總結&#xff1a;高階函數什么是高階函數&#xff1f;map()函數filter()函數reduce()函數參考可迭代對象 我們已經知道&#xff0c;可以直接作用于for循環的數據類型有以下幾種&#xff1a; 一類…

網絡閱讀開篇

網絡閱讀也符合馬太效應&#xff0c;投入的時間越多&#xff0c;獲取的有效信息卻越來越少&#xff0c;因此做出以下規定&#xff1a; 1、限制網絡閱讀時間&#xff1b; 2、每次閱讀做總結。 本來想的挺簡單的&#xff0c;隨便搜了一下&#xff0c;居然一部小心拜讀了兩位大神的…

python (第二章)數據結構

文章目錄2.5 對序列使用 和 建立由列表組成的列表2.6序列的增量賦值&#xff08;和&#xff09;關于 的謎題補充&#xff1a;extend()方法和有什么區別呢&#xff1f;2.7 list.sort方法和內置函數sorted(排序)2.8 用bisect來管理已排序的序列2.8.2用bisect.insort插入元素2.9 當…

數據庫 CURD測試題【簡單】

文章目錄1.組合兩個表基本信息要求答案2.第二高的薪水基本信息要求答案3.查找重復的電子郵箱基本信息要求答案4.超過經理收入的員工基本信息要求答案&#xff1a;5.超過5名學生的課信息&#xff1a;要求答案6.有趣的電影信息要求答案7.交換工資&#xff08;updeta,條件判斷&…

JAVA學習資料整理

今天偶然間發現之前一個群里發過的一篇關于JAVA學習資料的東西。本著服務大眾的精神&#xff0c;搬來了博客園&#xff1a; 《JAVA編程思想》第四版&#xff08;英文原版&#xff09;下載地址&#xff1a;http://115.com/file/e7fzi0fm《JAVA開發實戰經典》下載地址&#xff1a…

mysql快速了解

文章目錄數據庫了解&#xff1a;快速操作&#xff1a;安裝mysql啟動,關閉,重啟mysql服務連接mysql的root用戶創建數據庫刪除數據庫選擇數據庫mysql 數據類型MySQL 創建數據表MySQL 刪除數據表MySQL 插入數據MySQL 查詢數據MySQL WHERE 子句BINARY 關鍵字MySQL UPDATE 更新批量更…

javascript編程風格(粗略筆記)

1、空格 緊湊型&#xff1a;    project.MyClass function(arg1, arg2){  松散型&#xff1a;    for( i 0; i < length; i ){ 2、代碼行長度  最多80個字符 3、命名: 采用駝峰式方法命名(開始的第一個單詞小寫&#xff0c;之后的所有單詞首字母大寫)  var …

數據結構 面試題

文章目錄1.數組1.1 尋找數組中第二小的元素1.2 找到數組中第一個不重復出現的整數1.3合并兩個有序數組1.4 重新排列數組中的正值和負值2.棧2.1 前綴表達式&#xff0c;中綴表達式&#xff0c;后綴表達式2.1.1 中綴表達式轉化為后綴表達式2.1.2 中綴表達式轉化為前綴表達式2.2使…

WPF之無法觸發KeyDown或者KeyUp鍵盤事件

有時候我們可能在Panel(StackPanel、Canvas、Grid)上或者是在一些默認不支持Focus的控件上添加了KeyDown或者KeyUp&#xff0c;可是殘酷的現實告訴我們&#xff0c;這是無法觸發的&#xff0c;怎么辦呢&#xff0c;很簡單&#xff0c;只需一句代碼。 private void MouseLeftBut…

宣布在日本地區正式發布 Windows Azure

&#xfeff;&#xfeff;昨天&#xff0c;我與 Microsoft 日本的集團副總裁 Yasuyuki Higuchi 一同站在臺上&#xff0c;宣布在兩個新地區正式發布 Windows Azure&#xff1a;日本東部和日本西部。能夠親自見證 Microsoft 對日本市場的持續承諾&#xff0c;對我來說是莫大的榮…

運行cmd狀態下MySQL導入導出.sql文件

MySQL導入導出.sql文件步驟如下&#xff1a; 一.MySQL的命令行模式的設置&#xff1a; 桌面->我的電腦->屬性->環境變量->新建-> PATH“&#xff1b;path\mysql\bin;”其中path為MySQL的安裝路徑。 二.簡單的介紹一下命令行進入MySQL的方法&#xff1a; 1.C:\&g…

python中的collections

文章目錄deque(雙向列表)defaultdict(為不存在的key設置默認值)OrderedDictOrderedDict可以實現一個FIFO&#xff08;先進先出&#xff09;的dict&#xff0c;Counter參考collections是Python內建的一個集合模塊&#xff0c;提供了許多有用的集合類。deque(雙向列表) 使用list…

mysql 面試點

文章目錄mysql 運算符1.mysql運算符中的 !和Not的區別&#xff1f;CRUD1.條件判斷的用法2. not exits 和not in 的區別3. case when語句mysql函數1.to_days()連接1.什么時候選擇右連接&#xff0c;什么時候選擇左連接&#xff1f;mysql 運算符 1.mysql運算符中的 !和Not的區別…

[Windows Phone] 實作不同的地圖顯示模式

[Windows Phone] 實作不同的地圖顯示模式 原文:[Windows Phone] 實作不同的地圖顯示模式前言 本文章主要示范如何讓地圖有不同的模式產生&#xff0c;例如平面圖、地形圖、鳥瞰圖、鳥瞰圖含街道等。 這部分主要是調整 Map.CartographicMode 屬性&#xff0c;其中 MapCartograph…

數據庫 CURD測試題【中等】

文章目錄1.換座位&#xff08;交換相鄰的id&#xff09;基本信息要求答案[case when]2.分數排名(分組&#xff0c;排序)基本信息要求答案3.連續出現的數字(連接)信息要求答案4.第N高的薪水(函數)信息要求答案5.各個部門工資最高的員工(分組&#xff0c;連接)信息要求答案6.統計…

[STemWin教程入門篇]第一期:emWin介紹

特別說明&#xff1a;原創教程&#xff0c;未經許可禁止轉載&#xff0c;教程采用回復可見的形式&#xff0c;謝謝大家的支持。 armfly-x2,x3,v2,v3,v5開發板裸機和帶系統的emWin工程已經全部建立&#xff0c;鏈接如下&#xff1a; http://bbs.armfly.com/read.php?tid1830 SE…

python 棧【測試題】

文章目錄1.刪除最外層的括號信息要求答案2.棒球比賽信息示例答案3. 用棧實現隊列要求說明:答案4.用隊列模擬棧描述注意答案5.下一個更大的元素&#xff08;未解&#xff09;信息&#xff1a;示例&#xff1a;注意:答案&#xff1a;6.刪除字符串中的所有相鄰重復項信息示例&…