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

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

【ZOJ 2112】Dynamic Rankings

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

ZOJ 2112

題意

給你n個數,有q次操作,每次操作可以修改某一個數,或是求區間第k小值。(多組數據)

樣例輸入

2 5 3 3 2 1 4 7 Q 1 4 3 C 2 6 Q 2 5 3 5 3 3 2 1 4 7 Q 1 4 3 C 2 6 Q 2 5 3

樣例輸出

3 6 3 6

SOL

如果不考慮單點修改就是主席樹裸題。主席樹本質上使用前綴和維護的,查詢復雜度為O(1),但修改復雜度為O(n)。如果不用前綴和,查詢復雜度為O(n),修改復雜度為O(n)。(這不是廢話么…) 考慮在外面套上一層樹狀數組,使得查詢和修改復雜度均為O(logn)。

簡單的實現方式

普通的樹狀數組的每一個點存的都是某幾個數的和(和lowbit有關),那么本道題的每一個點存的都是一棵線段樹,并且相鄰線段樹之間用主席樹的方式連接。

時間復雜度分析

修改:每次最多對log(n)棵線段樹修改,每個節點中存的線段樹要修改log(n)次,最多加入(n+m)個數(最開始要放入n個數),所以時間復雜度為O((n+m)lognlogn)。 查詢:每次需要累加最多log(n)棵線段樹,每棵線段樹累加log(n)個節點,所以時間復雜度為O(mlognlogn)。

空間復雜度分析

每次操作修改log(n)棵線段樹,每棵線段樹修改log(n)個節點,所以空間復雜度為O((n+m)lognlogn)。

從這里可以可以看出時間復雜度和空間復雜度都是nlognlogn級別的,但是在ZOJ上內存限制只有64M,也就是說這種方式會MLE,如何解決?

靜態建樹+動態修改

分析數據范圍可以看出這道題目的m比較小,所以可以選擇一種神奇的方法:把查詢的區間分為兩步,第一步求出原區間,第二步加上修改的增量。第一步顯然就是裸的主席樹,第二步也就是沒有初值的修改,不同之處在于只要修改m就可以了??臻g復雜度級數沒有變,但是常數大概能小4~6倍,空間剛好可以卡過去。下面就用這種方法具體解釋如何實現。

建樹

為了自己能夠更好的掌握,這里的建樹和更新方法都采用裸二叉樹的方法。(還有許多方法,比如不需要用遞歸實現的,以后有空可以學習一下,基本上遞歸方式能夠看懂非遞歸方式就很簡單了)

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,int delta){ rt = ++tot; ls[rt] = ls[last]; rs[rt] = rs[last]; sum[rt] = sum[last] + delta; if (l == r) return; int m = (l + r) >> 1; if (p <= m) update(l,m,ls[rt],ls[last],p,delta); else update(m+1,r,rs[rt],rs[last],p,delta);}

查詢

個人感覺最難的部分就是查詢。從這里可以看出非遞歸方式寫起來真的非常清爽。。。特別是當樹套樹一層一層搞不清楚的時候寫成遞歸真的要死。。。 這里的S數組存的是樹狀數組里面每個節點代表的線段樹的根的編號(可以對比:root數組存的是原始數組里面每個節點代表的線段樹的根的編號),怎么更新S后面會講到。use1/2數組存的就是L-1和R的lowbit路徑。 int cnt = value2(R) - value1(L-1) + sum[ls[rrt]] - sum[ls[lrt]];這句話就是我剛才提到的“把查詢的區間分為兩步,第一步求出原區間,第二步加上修改的增量”。顯然value過程求的是增量,sum數組顯然是原區間的情況。

int value1(int x){ int re = 0; while (x > 0) {re += sum[ls[use1[x]]]; x -= lowbit(x);} return re;}int value2(int x){ int re = 0; while (x > 0) {re += sum[ls[use2[x]]]; x -= lowbit(x);} return re;}int Query(int L,int R,int k){ int lrt = root[L-1]; int rrt = root[R]; int l = 1,r = mm; for (int i = L - 1;i ; i -= lowbit(i)) use1[i] = S[i]; for (int i = R;i ; i -= lowbit(i)) use2[i] = S[i]; while (l < r) { int m = (l + r) >> 1; int cnt = value2(R) - value1(L-1) + sum[ls[rrt]] - sum[ls[lrt]]; if (k <= cnt) { r = m; for (int i = L - 1;i ; i -= lowbit(i)) use1[i] = ls[use1[i]]; for (int i = R;i ; i -= lowbit(i)) use2[i] = ls[use2[i]]; lrt = ls[lrt]; rrt = ls[rrt]; } else { l = m + 1; k = k - cnt; for (int i = L - 1;i > 0; i -= lowbit(i)) use1[i] = rs[use1[i]]; for (int i = R;i > 0; i -= lowbit(i)) use2[i] = rs[use2[i]]; lrt = rs[lrt]; rrt = rs[rrt]; } } return l;}

修改

S數組一開始全部連到root[0]上表示全部為空。接下來每次修改一個數就新開一棵線段樹并且用S記錄位置。

void change(int x,int p,int delta){ while (x<=n) { update(1,k,S[x],S[x],p,delta); x += lowbit(x); }}

完整代碼

#include<cmath>#include<cstdio>#include<vector>#include<cstring>#include<iomanip>#include<stdlib.h>#include<iostream>#include<algorithm>#define ll long long#define inf 1000000000#define mod 1000000007#define N 2500010#define M 60010using namespace std;struct data{int kind,l,r,k;}query[10010];char op[10];int T,n,mm,q,i,tot,k;int a[M],b[M],sum[N],ls[N],rs[N],root[M],S[M],use1[M],use2[M];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,int delta){ rt = ++tot; ls[rt] = ls[last]; rs[rt] = rs[last]; sum[rt] = sum[last] + delta; if (l == r) return; int m = (l + r) >> 1; if (p <= m) update(l,m,ls[rt],ls[last],p,delta); else update(m+1,r,rs[rt],rs[last],p,delta);}int lowbit(int x){return x&(-x);}int value1(int x){ int re = 0; while (x > 0) {re += sum[ls[use1[x]]]; x -= lowbit(x);} return re;}int value2(int x){ int re = 0; while (x > 0) {re += sum[ls[use2[x]]]; x -= lowbit(x);} return re;}int Query(int L,int R,int k){ int lrt = root[L-1]; int rrt = root[R]; int l = 1,r = mm; for (int i = L - 1;i ; i -= lowbit(i)) use1[i] = S[i]; for (int i = R;i ; i -= lowbit(i)) use2[i] = S[i]; while (l < r) { int m = (l + r) >> 1; int cnt = value2(R) - value1(L-1) + sum[ls[rrt]] - sum[ls[lrt]]; if (k <= cnt) { r = m; for (int i = L - 1;i ; i -= lowbit(i)) use1[i] = ls[use1[i]]; for (int i = R;i ; i -= lowbit(i)) use2[i] = ls[use2[i]]; lrt = ls[lrt]; rrt = ls[rrt]; } else { l = m + 1; k = k - cnt; for (int i = L - 1;i > 0; i -= lowbit(i)) use1[i] = rs[use1[i]]; for (int i = R;i > 0; i -= lowbit(i)) use2[i] = rs[use2[i]]; lrt = rs[lrt]; rrt = rs[rrt]; } } return l;}void change(int x,int p,int delta){ while (x<=n) { update(1,k,S[x],S[x],p,delta); x += lowbit(x); }}int hash(int x){ return lower_bound(b+1,b+k+1,x)-b;}int main(){ cin>>T; while (T--) { cin>>n>>q; for (i = 1;i <= n; i++) scanf("%d",&a[i]); for (i = 1;i <= n; i++) b[i] = a[i]; k = n; for (i = 1;i <= q; i++) { scanf("%s",op); if (op[0] == 'Q') { query[i].kind = 0; scanf("%d%d%d",&query[i].l,&query[i].r,&query[i].k); } else { query[i].kind = 1; scanf("%d%d",&query[i].l,&query[i].r); b[++k] = query[i].r; } } sort(b+1,b+k+1); k = unique(b+1,b+k+1) - (b+1); tot = 0; build(1,k,root[0]); for (i = 1;i <= n; i++) update(1,k,root[i],root[i-1],hash(a[i]),1); for (i = 1;i <= n; i++) S[i] = root[0]; mm = k; for (i = 1;i <= q; i++) { if (query[i].kind == 0)
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美日韩国产精品一区二区不卡中文| 中文字幕亚洲综合久久| 亚洲精品91美女久久久久久久| 欧美一级淫片播放口| 精品一区二区三区电影| 欧美大片在线影院| 免费97视频在线精品国自产拍| 亚洲第一网站免费视频| 久久久www成人免费精品| 欧美精品videossex88| 日韩午夜在线视频| 2021国产精品视频| 国产亚洲精品91在线| 国产欧美韩国高清| 日韩激情av在线免费观看| 91久久久久久久久久久久久| 日韩av色综合| 色yeye香蕉凹凸一区二区av| 91精品国产综合久久久久久久久| 国产日韩欧美中文| www.日韩av.com| 成人免费在线视频网站| 亚洲黄色www网站| 国产欧美精品va在线观看| 久久久精品中文字幕| 久久精品视频免费播放| 全亚洲最色的网站在线观看| 欧美尺度大的性做爰视频| 国产免费一区视频观看免费| 精品无人国产偷自产在线| 亚洲国产另类久久精品| 国产精品美女久久久免费| 福利二区91精品bt7086| 国产精品久久久91| 欧洲成人免费视频| 国产日韩欧美一二三区| 亚洲精品之草原avav久久| 国产精品99免视看9| 国产精品欧美日韩一区二区| 国产精品午夜一区二区欲梦| 欧美性xxxx极品hd满灌| 欧美午夜丰满在线18影院| 亚洲色图色老头| 国产国语刺激对白av不卡| 日韩精品高清在线| 欧美精品成人91久久久久久久| 亚洲综合一区二区不卡| 国产精品mp4| 国产女精品视频网站免费| 中文字幕亚洲综合久久| 国产精品白嫩美女在线观看| 日韩高清人体午夜| 日韩a**站在线观看| 成人久久18免费网站图片| 欧美成人免费一级人片100| 国产日韩欧美影视| 九九热精品在线| 日韩国产精品亚洲а∨天堂免| 88xx成人精品| 久久久久久国产三级电影| 精品国产欧美一区二区五十路| 欧美日韩色婷婷| 欧美激情综合色综合啪啪五月| 日本成熟性欧美| 亚洲综合一区二区不卡| 91精品国产91| 欧美性色视频在线| 永久免费精品影视网站| 国产福利精品视频| 欧美在线视频免费| 日韩在线中文视频| 久久成人精品电影| 亚洲精品第一国产综合精品| 97在线日本国产| 国外成人在线播放| 精品视频www| 日本免费久久高清视频| 国产精品99一区| 日韩精品免费看| 欧美体内谢she精2性欧美| 青青草99啪国产免费| 日韩在线中文字幕| 少妇精69xxtheporn| 亚洲欧美制服第一页| 久久久这里只有精品视频| 这里只有精品在线观看| 欧美老少做受xxxx高潮| 日韩中文在线视频| 精品福利视频导航| 97色伦亚洲国产| 欧美黄网免费在线观看| 欧美日韩第一视频| 亚洲第一区中文99精品| 欧美午夜精品伦理| 18一19gay欧美视频网站| 尤物tv国产一区| 久久久久久久久久久亚洲| 亚洲激情视频在线观看| 亚洲www永久成人夜色| 国产日韩在线精品av| 日韩女优在线播放| 久久国产精品久久国产精品| 国产精品人人做人人爽| 一区二区欧美激情| 欧美精品久久久久久久| 亚洲人成网7777777国产| 久热精品视频在线观看| 日本久久亚洲电影| 国产精品第一页在线| 亚洲va码欧洲m码| 日韩中文字幕网址| 国产欧美在线播放| 欧美国产日韩一区二区三区| 欧美激情精品久久久久久大尺度| 日韩电影在线观看中文字幕| 日韩av一区二区在线| 久久资源免费视频| 成人性生交大片免费观看嘿嘿视频| 人妖精品videosex性欧美| 日韩有码视频在线| 亚洲一区免费网站| 亚洲女人被黑人巨大进入al| 亚洲国产精品va在线观看黑人| 日韩av片免费在线观看| 日韩中文字幕av| 黑人巨大精品欧美一区二区三区| 国产黑人绿帽在线第一区| 亚洲精品欧美日韩专区| 日韩电影中文字幕一区| 久久精品色欧美aⅴ一区二区| 日本高清视频一区| 日韩资源在线观看| 亚洲天堂男人天堂女人天堂| 欧美成人在线影院| 日韩欧美精品网站| 性色av一区二区三区红粉影视| 久久久影视精品| 久久久国产精彩视频美女艺术照福利| 日韩精品视频在线播放| 伊人久久久久久久久久| 欧美日韩午夜激情| 亚洲激情视频在线播放| 久久国产精品影视| 国产视频丨精品|在线观看| 久久九九热免费视频| 日本精品视频网站| 久久久久久美女| 中文字幕免费国产精品| 日韩av在线精品| 亚洲精品免费一区二区三区| 亚洲新中文字幕| 欧美在线视频一区二区| 精品视频在线导航| 久久99亚洲精品| 国内揄拍国内精品| 91av视频在线| 91系列在线观看| 一区二区三欧美| 中文字幕日韩欧美在线视频| 中文字幕久久精品| 亚洲精品免费一区二区三区| 国产性色av一区二区| 草民午夜欧美限制a级福利片| 91色视频在线导航|