描述
初始有乙個空集,依次插入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 ...