區間第k大

2022-08-23 21:15:15 字數 3504 閱讀 6565

歸併樹:

#include#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define ll long long

#define max(x,y) (x)>(y)?(x):(y)

#define min(x,y) (x)>(y)?(y):(x)

#define cls(name,x) memset(name,x,sizeof(name))

using

namespace

std;

const

int inf=1

<<28

;const

int maxn=50010

;const

int maxm=110

;const

int mod=1e9+7

;const

double pi=acos(-1.0

);int

n;struct

node

tree[maxn*4

];int

num[maxn];

void build(int l,int r,int

x)

int mid=(l+r)/2

; build(l,mid,x*2

); build(mid+1,r,x*2+1

);

int i=0,j=0,k=0

;

while(i2].len&&j2+1

].len)

while(i2

].len)

tree[x].num[k++]=tree[x*2].num[i++];

while(j2+1

].len)

tree[x].num[k++]=tree[x*2+1].num[j++];

}int querry(int ql,int qr,int temp,int l,int r,int

x)

return

tl; }

int mid=(l+r)/2

;

if(qr<=mid)

return querry(ql,qr,temp,l,mid,x*2

);

else

if(ql>=mid+1

)

return querry(ql,qr,temp,mid+1,r,x*2+1

);

else

return querry(ql,mid,temp,l,mid,x*2)+querry(mid+1,qr,temp,mid+1,r,x*2+1);}

intmain()

if(querry(a+1,b+1,tree[1].num[r],1,n,1)==b-a-c+1

) printf(

"%d\n

",tree[1

].num[r]);

else

printf(

"%d\n

",tree[1

].num[l]);}}

return0;

}

劃分樹:

#include#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define ll long long

#define pb push_back

#define max(x,y) ((x)>(y)?(x):(y))

#define min(x,y) ((x)>(y)?(y):(x))

#define cls(name,x) memset(name,x,sizeof(name))

#define fs first

#define sc second

#define mp make_pair

#define l(x) (1<#define next next

using

namespace

std;

const

int inf=1e9+10

;const ll llinf=1e16+10

;const

int maxn=4e5+10

;const

int maxm=1e3+10

;const

int mod=1e9+7

;int

n,m;

struct

node

tree[maxn*4

];int

sorted[maxn];

void init(int l,int r,int

x)void build(int l,int r,int x)//

必須是穩定的快排

else tree[x*2+1].num[1+k2++]=tree[x].num[i];

}else tree[x*2+1].num[1+k2++]=tree[x].num[i];

tree[x].c[i]=k1;

}build(l,mid,x*2

); build(mid+1,r,x*2+1);}

int query(int ql,int qr,int k,int l,int r,int x)//

返回[ql,qr]第k小的數

int cquery(int ql,int qr,int k,int l,int r,int x)//

返回[ql,qr]小於等於k的數量

int cl=tree[x].c[qr-l+1]-tree[x].c[ql-1-l+1];//

[ql,qr]中有多少進入了左子樹

int cr=qr-ql+1-cl;//

[ql,qr]中有多少進入了右子樹

int mid=(l+r)/2

;

int tl=tree[x].c[ql-1-l+1]-tree[x].c[l-1-l+1];//

[l,ql-1]中有多少進入了左子樹

int tr=ql-1-l+1-tl;//

[l,ql-1]中有多少進入了右子樹

if(sorted[mid]<=k)

return cl+cquery(mid+1+tr,mid+1+tr+cr-1,k,mid+1,r,x*2+1

);

else

return cquery(l+tl,l+tl+cl-1,k,l,mid,x*2);}

intmain()

}return0;

}

區間第k大

問題描述 給定乙個序列,每次詢問序列中第l個數到第r個數中第k大的數是哪個。輸入格式 第一行包含乙個數n,表示序列長度。第二行包含n個正整數,表示給定的序列。第三個包含乙個正整數m,表示詢問個數。接下來m行,每行三個數l,r,k,表示詢問序列從左往右第l個數到第r個數中,從大往小第k大的數是哪個。序...

求區間第k大

int a mx void insert int a,int l,int r int divide int a,int l,int r 劃分子問題 a l x return l int select int s,int l,int r,int k,int len 返回s陣列l r的第k大數的下標 w...

區間第k大(主席樹)

學了一下主席樹模板題,當初看了網上的主席樹講解都沒有看懂,後面看了嗶哩嗶哩的uestc的主席樹,終於看懂了思想。每次更新的複雜度都為logn。每次更新的話就是對要更新的點路徑上的點重新更加乙個,然後進行對沒有影響的那些進行連邊。然後用乙個root記錄每乙個線段樹的根節點下標。include incl...