全稱是可持久化權值線段樹(以前一直分不清可持久化線段樹和主席樹的區別)
但實際上寫法跟可持久化trie沒什麼區別,維護權值就ok了
那就不講了
description
jz擁有乙個很大的野生動物園。這個動物園坐落在乙個狹長的山谷內,這個區域從南到北被劃分成n個區域,每個區域都飼養著一頭獅子。這些獅子從北到南編號為1,2,3,…,n。每頭獅子都有乙個覓食能力值ai,ai越小覓食能力越強。飼養員西西決定對獅子進行m次投喂,每次投喂都選擇乙個區間[i,j],從中選取覓食能力值第k強的獅子進行投喂。值得注意的是,西西不願意對某些區域進行過多的投喂,他認為這樣有悖公平。因此西西的投喂區間是互不包含的(即區間[1,10]不會與[3,4]或[5,10]同時存在,但可以與[9,11]或[10,20]一起)。同一區間也只會出現一次。你的任務就是算出每次投喂後,食物被哪頭獅子吃掉了。
input
覓食能力值。(1<=能力值<=maxlongint)。此後m行,每行描述一次投喂。第t+2的三個數i,j,k表示在第t次投喂中,西西選擇了區間[i,j]內覓食能力值第k強的獅子進行投喂。
output
輸出檔案有m行,每行乙個整數。第i行的整數表示在第i次投喂中吃到食物的獅子的覓食能力值。
sample input
7 2
1 5 2 6 3 7 4
1 5 3
2 7 1
sample output 3 2
data constraint
hint
對於100%的資料,有1<=n<=100000,1<=m<=50000。
區間第k大……標準的主席樹例題
維護每個範圍內數的個數,然後[r]-[l-1],樹上二分查詢
#include
#include
#include
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define mx 2147483647
using namespace std;
inttr[5000001][3];
int n,i,j,k,l,r,q,s,len;
void new(int t,int
x)void change(int t,long long l,long long r,int
x) else
}void find(int t,int t,long long l,long long r,int
s) if (tr[tr[t][1]][0]-tr[tr[t][1]][0]>=s)
find(tr[t][1],tr[t][1],l,mid,s);
else
find(tr[t][2],tr[t][2],mid+1,r,s-(tr[tr[t][1]][0]-tr[tr[t][1]][0]));
}int main()
for (;q;q--)
return
0;}
description
有乙個長度為n的陣列。m次詢問,每次詢問乙個區間內最小沒有出現過的自然數。
input
第一行n,m。
第二行為n個數。
從第三行開始,每行乙個詢問l,r。
output
一行乙個數,表示每個詢問的答案。
sample input
5 52 1 0 2 1
3 32 3
2 41 2
3 5
sample output
1data constraint
對於30%的資料:
1<=n,m<=1000
對於100%的資料:
1<=n,m<=200000
0<=ai<=10^9
1<=l<=r<=n
維護每個範圍內的數出現次數,之後二分+奇怪剪枝
如果左區間內的數出現次數《區間長度,那麼就一定在左區間,否則都有可能
(實際就是暴力)
#include
#include
#include
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define min(x,y) (x#define mx 2147483647
using namespace std;
inttr[10000001][3];
int n,i,j,k,l,r,q,s,len,ans;
void new(int t,int
x)void change(int t,long long l,long long r,int
x) else
}void find(int t,int t,long long l,long long r)
find(tr[t][1],tr[t][1],l,mid);
if (ans<123456789) return;
if (tr[tr[t][1]][0]-tr[tr[t][1]][0]>=r-mid)
find(tr[t][2],tr[t][2],mid+1,r);
}int main()
for (;q;q--)
return
0;}
維護到當前位置時區間內的值出現的min(最右位置)
然後乙個二分(從r開始),如果區間內所有數的最右位置都≥l以內就在右邊,否則在左邊
話說我還想過建10^9棵線段樹
#include
#include
#include
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define min(x,y) (x#define mx 2147483647
using namespace std;
inttr[10000001][3];
int n,i,l,r,q,s,len;
void new(int t,int
x)void change(int t,long long l,long long r,int
x) if (x
<=mid)
else
tr[t][0]=min(tr[tr[t][1]][0],tr[tr[t][2]][0]);
}void find(int t,long long l,long long r,int
s) if (tr[tr[t][1]][0]find(tr[t][1],l,mid,s);
else
find(tr[t][2],mid+1,r,s);
}int main()
for (;q;q--)
return
0;}
description
在組合遊戲中計算狀態的 sg 值時,我們常常會遇到 mex 函式。mex(s) 的值為集合 s 中沒有出現過的最小自然數。例如,mex() = 0、mex() = 4。
給定長度為 n 的序列 a。現有 m 次詢問,每次給定 l 和 r,詢問區間 [l,r] 的數構成的集合的 mex 值。
input
輸入資料的第一行包含三個整數 n、m 和 t,其中 t 為 0 或者 1,表示資料型別。
接下來一行,包含 n 個非負整數,為序列 a。
接下來 m 行,每行描述乙個詢問。第 i 行包含兩個正整數 l 和 r,代表第 i 次詢問的區間的左右端點。如果 t = 1,則詢問進行了加密,從第二個詢問開始,讀入的 l 和 r 異或前一次詢問的答案才是真正的詢問左右端點。
output
對於每個詢問,輸出一行,代表詢問區間的 mex 值。
sample input
5 4 0
2 1 0 2 1
3 3
2 3
2 4
1 2
sample output
1 2 3 0
#include
#include
#include
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define min(x,y) (x#define mx 2147483647
using namespace std;
inttr[10000001][3];
int n,i,l,r,q,s,len,size,ans;
void new(int t,int
x)void change(int t,long long l,long long r,int
x) if (x
<=mid)
else
tr[t][0]=min(tr[tr[t][1]][0],tr[tr[t][2]][0]);
}void find(int t,long long l,long long r,int
s) if (tr[tr[t][1]][0]find(tr[t][1],l,mid,s);
else
find(tr[t][2],mid+1,r,s);
}int main()
for (;q;q--)
fclose(stdin);
fclose(stdout);
return
0;}
主席樹 入門
思想類似字首和,訪問某狀態的線段樹可通過末減初狀態進行求解。hdu4417 第二道模板題 有很多細節需要注意。1.題目給定ai的高度可能為0,但通過離散化事實上不影響結論。2.給定的訪問區間 x,y 以及高度h也可能為零,因而x,y需對應 查詢依舊是root y root x 1 3.對於高度h,為...
主席樹入門
推薦部落格 早在很久之前就聽過主席樹這個名詞,不過一直沒有去學,當時想的是先把線段樹學明白了,今天想學這個是因為一場 cf。主席樹其實就是由 n 棵權值線段樹組成,並且你要保留著 i 棵線段樹的根節點,這 i 棵線段樹其實就可以看成是不同的歷史的版本,現在如果想讓我們查詢某一段區間時,我們直接做差就...
Just h index(主席樹裸題)
just h index 題意 輸入第一行給了 n q 代表有 n 個數 q 次詢問,第二行給出這 n 個數,每次詢問乙個區間,答出乙個最大的數 h 使得這個區間裡大於等於 h 的數的個數大於等 h 題解 見 吧,比較好理解的,主席樹 ac code 1 主席樹是多個權值線段樹 2 include ...