P2839 國家集訓隊 middle

2022-05-07 21:06:11 字數 1905 閱讀 9558

• 提一下靜態區間第k小的nlog2n的做法:

1. 建關於排名的主席樹(按排名順序建樹)。

2. 二分答案。

• 這樣做靜態區間第k小的雖然有些zz,但它的意義在於將線段樹

維護的物件改變了。

1 #include2

using

namespace

std;

3int

n,m,cnt;

4int a[5

],midd;

5int val[20050];6

int pos[20050];7

int root[20050];8

int son[500050][2];9

struct

node

1017 }w[500050

],ans;

18node merge(node a,node b)

1926

bool cmp(int x,int

y)27

30void build(int &u,int l,int

r)31

39int mid=(l+r)>>1

;40 build(son[u][0

],l,mid);

41 build(son[u][1],mid+1

,r);

42 w[u]=merge(w[son[u][0]],w[son[u][1

]]);43}

44void calc(int &u,int v,int l,int r,int

pos)

4555

int mid=(l+r)>>1;56

if(pos<=mid) calc(son[u][0],son[v][0

],l,mid,pos);

57else calc(son[u][1],son[v][1],mid+1

,r,pos);

58 w[u]=merge(w[son[u][0]],w[son[u][1

]]);59}

60void ask(int u,int l,int r,int l,int

r)61

67int mid=(l+r)>>1;68

if(l<=mid) ask(son[u][0

],l,mid,l,r);

69if(r>mid) ask(son[u][1],mid+1

,r,l,r);70}

71bool check(int

u)72

80if(a[1]<=a[2

])81

86if(a[3]+1

<=a[4

])87

92return sum>=0;93

}94intmain()

95102 sort(pos+1,pos+n+1

,cmp);

103 build(root[0],1

,n);

104for(int i=1;i<=n;++i)

105 calc(root[i],root[i-1],1

,n,pos[i]);

106 scanf("

%d",&m);

107while(m--)

108114 sort(a+1,a+5

);115

int l=1,r=n;

116while(l

117122 midd=val[pos[l+1

]];123 printf("

%d\n

",midd);

124}

125return0;

126 }

view code

Luogu P2839 國家集訓隊 middle

首先 b,c 是必選的,然後選一段 a,b 的字尾和一段 c,d 的字首 都可空 對於中位數 這裡中位數採用這道題的定義 有個常見的處理方式 二分 mid,將 0,則說明 mid 的佔到了一半以上,即中位數 mid。採用這種處理方式,二分中位數,由於要中位數盡量大,所以要貪心,選字尾和字首使得大於等...

P2839 國家集訓隊 middle 解題報告

給乙個長度為 n nn 的序列。多次詢問,每次給出四個引數 a,b c,d a,b,c,d a,b,c,d 要求找乙個子區間 l,r l,r l,r 滿足 a l b,c r d a le l le b,c le r le d a l b,c r d,使得子區間的中位數最大。輸出中位數的最大值。首先...

解題報告 P2839 國家集訓隊 middle

絕世好題 首先對於求區間 l,r 的中位數,有乙個套路可以套 二分乙個值 d 每次將區間內 的點設為 1 將 ge d 的點設為 1 當區間和 ge 0 時 d 值過大或剛好,若 0 則 d 值過小。我們繼續觀察題目。我們發現,每次詢問的區間不固定,但是 b 1,c 1 這個區間是必須選擇的,所以我...