3637 Rollcall 離線 權值線段樹

2021-09-10 23:14:33 字數 1973 閱讀 2230

描述

初始有乙個空集,依次插入n個數ai。有m次詢問bj,表示詢問第bj個數加入集合後的排名為j的數是多少

輸入

第一行是兩個整數n,m

接下來一行有n個整數,ai

接下來一行有m個整數bj,保證資料合法

輸出

m行,回答每個詢問

樣例輸入 [複製]

7 49 7 2 8 14 1 8

1 2 6 6

樣例輸出 [複製]99

78【說明】

第一次詢問,當前幾何,1th=9

第二次詢問,當前集合{9,7}的第2=9

第三次詢問,當前集合的第3=7

第四次詢問,當前幾何的第4=8

【資料規模】

40%的資料保證 n ≤ 1000

100%的資料保證1≤m≤n≤30000;0≤ai<2^32

思路:

離線+權值線段樹//要開long long。。。

#include

#define sf scanf

#define lc (p<<1)

#define rc ((p<<1)|1)

#define int long long

//沒開long long見祖宗。。。。

//真沒開long long。。。。

//int <=2e31-1

using

namespace std;

const

int maxn=

3e4+10;

int num[maxn]

,n,m,ans[maxn]

;int sum[maxn<<2]

,hash[maxn<<1]

,tot=0;

vector <

int> g[maxn]

;void

change

(int p,

int l,

int r,

int k)

int mid=

(l+r)

>>1;

if(k>mid)

change

(rc,mid+

1,r,k)

;else

change

(lc,l,mid,k)

; sum[p]

=sum[lc]

+sum[rc];}

intquery

(int p,

int l,

int r,

int k)

int mid=

(l+r)

>>1;

if(k<=sum[lc]

)return

query

(lc,l,mid,k)

;else

return

query

(rc,mid+

1,r,k-sum[lc]);

}signed

main()

for(

int i=

1;i<=m;

++i)

sort

(hash+

1,hash+n+1)

; tot=

unique

(hash+

1,hash+n+1)

-hash-1;

for(

int i=

1;i<=n;

++i)

}for

(int i=

1;i<=m;

++i)

printf

("%lld\n"

,ans[i]);

return0;

}

權值線段樹

維護全域性的值域資訊,每個節點記錄的是該值域的值出現的總次數。使用二分的思想 離散化的時候,需要用到 支援查詢全域性k小值,全域性rank,前驅,後繼等。單詞操作時間複雜度為o logn 空間複雜度為o n 相對於平衡樹的優勢 簡單,速度快 劣勢 值域較大時,我們需要離散化,變成離線資料結構 我認為...

權值線段樹

include using namespace std int n,m,tre 10003 4 laz 10003 4 void pushdown int num void update int num,int le,int ri,int x,int y,int z pushdown num int...

權值線段樹

權值線段樹是線段樹的一種,但是它與線段樹不同 線段樹的每個結點是用來維護一段區間的最大值或總和 而權值線段樹的每個結點儲存的一段區間有多少個數 權值線段樹主要用來查詢區間第k大或者第k小的值 現在有乙個陣列x 10 對陣列排序後為x 10 每個數的個數如下 1 32 2 3 24 1 5 18 1 ...