亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

【POJ 2104】K-th Number&主席樹詳解

2019-11-11 07:55:17
字體:
來源:轉載
供稿:網友

POJ 2104

題意

給定1到n的排列,每次詢問某一區間內的第k小值。

樣例輸入

7 3 1 5 2 6 3 7 4 2 5 3 4 4 1 1 7 3

樣例輸出

5 6 3


主席樹介紹

可持久化線段樹,函數式線段樹。 有點抽象,能夠理解但還不是很熟練,代碼不長,但是非常簡練,有很多技巧,目前當做黑箱。

可持久化:每次操作盡量用新節點表示而不是修改原節點,這樣就能保留所有歷史信息。 函數式:函數式編程里變量常常是不變的,線段樹的函數式寫法就是這樣。

我們用區間k小值來解釋。

一些預處理

離散化(排序+去重),其實本道題不需要這個操作。 下面的代碼用到了STL的很多技巧,用unique()函數去重,用lower_bound()重新映射a數組。

for (i = 1;i <= n; i++) scanf("%d",&a[i]);for (i = 1;i <= n; i++) b[i] = a[i];sort(b+1,b+n+1);k = unique(b+1,b+n+1) - (b+1);for (i = 1;i <= n; i++) a[i] = lower_bound(b+1,b+k+1,a[i])-b;

假設求整個區間的k小值

這個問題可以用AVL樹做,但是這里介紹一種類似平衡樹的方法。假設某個節點的區間為[l,r],則這個節點記錄的是在a數組中有多少個a[i]滿足l<=a[i]<=r。這樣搜索第k小值時,如果左孩子數量小于k則k小值在左子樹中,反之則在右子樹中。復雜度log(n)。

對于任意區間[L,R]

建立n棵線段樹,每棵維護[1,i]的數字出現情況。 顯然這n棵線段樹每個節點代表的區間都是一樣的,所以這n棵線段樹同構。 用第R棵線段樹去“減”第(L-1)棵線段樹,得出來的結果就是區間[L,R]的情況,對這棵樹套用一遍上面求整個區間的方法就可以求出[L,R]中的k小值。

如何節約空間

上面的方法看起來還是比較具體的,但是會MLE(n棵線段樹)。 下面的優化就是主席樹的精髓:如何扔掉重復的節點。有點抽象,這段話看懂了就比較輕松了。

我們發現,第i棵線段樹和第i+1棵線段樹的區別在于加入了a[i+1]這個數,而a[i+1]在第i棵樹上從根出發向下走,走過的節點+1就變成了第i+1棵線段樹。(你可以自己畫一下看看有什么不同)

也就是說相鄰兩棵線段樹之間不同節點個數至多為log(n)個,換句話說剩下這么多的節點都是一樣的! 那么重復的節點就可以扔掉了。比如說一個節點的左孩子是重復的,那么我不需要多開一個節點,而是直接連到前一棵樹上。 看起來比較復雜,但是編程中有很多技巧,最后代碼比普通線段樹還短。 P.S. 怕以后忘記這里寫的會很詳細。

sol

預處理這里就不再寫了。

建樹

現在連建樹都要重新寫了TAT。 其實只要建一棵空樹即可,后面的樹都是連到這棵樹上。 但是后面再update和query的時候有一個問題:左孩子和右孩子并不能簡單的乘2和乘2加1,如何解決?

//root[i]表示第i棵樹的根的位置void build(int l,int r,int &rt){ rt = ++tot; sum[rt] = 0; if (l == r) return; int m = (l + r) >> 1; build(l,m,ls[rt]); build(m+1,r,rs[rt]);}...tot = 0;build(1,k,root[0]);

用最樸素的方法:一個一個累加! 這里有一個技巧就是用了&,也就是說等到搜到這個點的時候自然會把這個點的位置給傳回來。這個技巧剩下了不少代碼,在后面的update和query中可以自己體會。

更新

//ls表示左孩子位置 rs表示右孩子位置 last表示前一棵樹、當前節點的位置void update(int l,int r,int &rt,int last,int p){ rt = ++tot; ls[rt] = ls[last]; rs[rt] = rs[last];//暫時兩個孩子都連到前一棵樹的對應孩子上 sum[rt] = sum[last] + 1;//這一步可以解釋是哪log(n)個點的值發生了修改! if (l == r) return; int m = (l + r) >> 1; if (p <= m) update(l,m,ls[rt],ls[last],p); else update(m+1,r,rs[rt],rs[last],p);//修改的那個節點開辟出一個新節點 ls/rs會回傳新的節點的位置!前面講到過}...for (i = 1;i <= n; i++) update(1,k,root[i],root[i-1],a[i]);

這樣一來就把這“n棵線段樹”都建好了??梢钥闯鲭m然節點總數為nlog(n),但是卻把所有的情況都記錄下來了,這就是“可持久化”。

查詢

int query(int ss,int tt,int l,int r,int k){ if (l == r) return l; int m = (l + r) >> 1; int cnt = sum[ls[tt]] - sum[ls[ss]];//用第tt棵線段樹減去第ss棵線段樹 if (k <= cnt) return query(ls[ss],ls[tt],l,m,k); else return query(rs[ss],rs[tt],m+1,r,k-cnt);}...while (q--) { scanf("%d%d%d",&ql,&qr,&qk); int res = query(root[ql-1],root[qr],1,k,qk); 有了前面的鋪墊,查詢就比較簡單了。

完整代碼

#include<cmath>#include<cstdio>#include<vector>#include<cstring>#include<ioman
ip>#include<stdlib.h>#include<iostream>#include<algorithm>#define ll long long#define inf 1000000000#define mod 1000000007#define N 100000using namespace std;int a[N],b[N],root[N*20],ls[N*20],rs[N*20],sum[N*20];int n,q,i,tot,k,ql,qr,qk;void build(int l,int r,int &rt){ rt = ++tot; sum[rt] = 0; if (l == r) return; int m = (l + r) >> 1; build(l,m,ls[rt]); build(m+1,r,rs[rt]);}void update(int l,int r,int &rt,int last,int p){ rt = ++tot; ls[rt] = ls[last]; rs[rt] = rs[last]; sum[rt] = sum[last] + 1; if (l == r) return; int m = (l + r) >> 1; if (p <= m) update(l,m,ls[rt],ls[last],p); else update(m+1,r,rs[rt],rs[last],p);}int query(int ss,int tt,int l,int r,int k){ if (l == r) return l; int m = (l + r) >> 1; int cnt = sum[ls[tt]] - sum[ls[ss]]; if (k <= cnt) return query(ls[ss],ls[tt],l,m,k); else return query(rs[ss],rs[tt],m+1,r,k-cnt);}int main(){ cin>>n>>q; for (i = 1;i <= n; i++) scanf("%d",&a[i]); for (i = 1;i <= n; i++) b[i] = a[i]; sort(b+1,b+n+1); k = unique(b+1,b+n+1) - (b+1); for (i = 1;i <= n; i++) a[i] = lower_bound(b+1,b+k+1,a[i])-b; tot = 0; build(1,k,root[0]); for (i = 1;i <= n; i++) update(1,k,root[i],root[i-1],a[i]); while (q--) { scanf("%d%d%d",&ql,&qr,&qk); int res = query(root[ql-1],root[qr],1,k,qk); printf("%d/n",b[res]); } return 0;}
上一篇:flex4 spark 布局

下一篇:【POJ 3667】Hotel

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久亚洲欧美日韩精品专区| 国产精品精品一区二区三区午夜版| 国产精品第10页| 成人精品一区二区三区电影黑人| 日本老师69xxx| 国内精品久久久久久久久| 日韩精品免费综合视频在线播放| 疯狂欧美牲乱大交777| 中文字幕亚洲综合| 成人有码视频在线播放| 亚洲经典中文字幕| 一区二区福利视频| 亚洲国产日韩欧美在线99| 一区二区日韩精品| 一个人看的www久久| 91麻豆国产语对白在线观看| 一区二区三区四区在线观看视频| 亚洲综合大片69999| 91黄色8090| 2018中文字幕一区二区三区| 91精品国产91久久久久| 国产精品久久久久7777婷婷| 亚洲午夜精品视频| 国产精品高潮呻吟久久av无限| 成人a在线观看| 欧美日韩精品国产| 成人免费午夜电影| 亚洲综合av影视| 午夜精品一区二区三区在线视| 欧美裸体视频网站| 色香阁99久久精品久久久| 成人激情视频在线| 欧美大肥婆大肥bbbbb| 北条麻妃一区二区三区中文字幕| 97在线免费观看| 精品久久久香蕉免费精品视频| 狠狠做深爱婷婷久久综合一区| 俺去亚洲欧洲欧美日韩| 欧美高清视频一区二区| 日本高清不卡的在线| 亚洲福利小视频| 日韩在线观看你懂的| 日韩欧美亚洲成人| 欧美裸体视频网站| 美日韩精品免费观看视频| 精品福利在线视频| 欧美成人免费一级人片100| 日产精品久久久一区二区福利| 日韩欧美福利视频| 成人夜晚看av| 欧美成人免费网| 欧美高跟鞋交xxxxhd| 欧美日韩午夜剧场| 久久久久久久久中文字幕| 欧美肥老太性生活视频| 久久久久久久久久久国产| 亚洲a在线观看| 热久久99这里有精品| 色香阁99久久精品久久久| 日本一本a高清免费不卡| 国产精品69久久久久| 97精品国产91久久久久久| 91香蕉嫩草神马影院在线观看| 在线视频日韩精品| 最好看的2019的中文字幕视频| 欧美日韩在线一区| 日本精品久久中文字幕佐佐木| 亚洲一级黄色av| 国产精品盗摄久久久| 成人xvideos免费视频| 久久久免费电影| 在线亚洲男人天堂| 在线播放国产一区二区三区| 日韩中文字幕免费视频| 欧美激情图片区| 欧美日韩国产一区中文午夜| 这里精品视频免费| 欧美大片在线看| 亚洲韩国欧洲国产日产av| 国内精品久久久久影院 日本资源| 国产精品视频免费观看www| 日韩电影大片中文字幕| 亚洲精品影视在线观看| 亚洲视频日韩精品| 国产欧美精品久久久| 韩国19禁主播vip福利视频| 国产午夜精品免费一区二区三区| 秋霞成人午夜鲁丝一区二区三区| 成人伊人精品色xxxx视频| 韩国19禁主播vip福利视频| 亚洲在线观看视频| 亚洲小视频在线观看| 午夜精品久久久久久久99热| 韩曰欧美视频免费观看| 午夜精品一区二区三区在线视频| 97涩涩爰在线观看亚洲| 亚洲国内精品视频| 久久久久久这里只有精品| 亚洲电影免费观看高清完整版在线| 少妇激情综合网| 在线观看国产精品91| 国产成人精品国内自产拍免费看| 一区二区三区黄色| 91av网站在线播放| 欧美日韩中国免费专区在线看| 97精品久久久| 亚洲福利视频免费观看| 国产亚洲精品一区二555| 亚洲成人在线视频播放| 国产91色在线|| 国产精品亚洲第一区| 久久久视频免费观看| 日本午夜在线亚洲.国产| 国产日韩欧美黄色| 亚洲最大福利视频| 亚洲视频专区在线| 伊人男人综合视频网| 国产成人啪精品视频免费网| 91国内产香蕉| 97在线观看免费高清| 97在线免费观看视频| 亚洲欧美日韩第一区| 久久精品国产精品亚洲| 中文字幕在线观看亚洲| 欧美成人自拍视频| 亚洲电影免费观看高清| 91精品久久久久久久| 国产精品99久久久久久www| 日韩精品中文字幕有码专区| 国内精品中文字幕| 国产精品美女无圣光视频| 久久久久久久97| 亚洲欧美一区二区三区久久| 琪琪亚洲精品午夜在线| 欧美又大粗又爽又黄大片视频| 欧美性感美女h网站在线观看免费| 欧美成人在线免费视频| 欧美日产国产成人免费图片| 91麻豆国产语对白在线观看| 国产日韩精品在线| 欧美一级在线亚洲天堂| 亚洲欧美日韩区| 国产亚洲一级高清| 久久伊人色综合| 91tv亚洲精品香蕉国产一区7ujn| 日韩精品免费一线在线观看| 久久久人成影片一区二区三区| 不卡av电影在线观看| 国产精品久久久久久久久久免费| 欧美性videos高清精品| 日本精品在线视频| 日韩精品免费在线视频观看| 欧美丰满少妇xxxxx做受| 亚洲va码欧洲m码| 欧美成人中文字幕| 久久精品视频在线播放| 精品久久久久久亚洲国产300| 欧美大片第1页| 亚洲黄色成人网| 97国产一区二区精品久久呦| 91免费高清视频| 色老头一区二区三区| 日本精品va在线观看| 18性欧美xxxⅹ性满足|