• 提一下靜態區間第k小的nlog2n的做法:
1. 建關於排名的主席樹(按排名順序建樹)。
2. 二分答案。
• 這樣做靜態區間第k小的雖然有些zz,但它的意義在於將線段樹
維護的物件改變了。
1 #include2view codeusing
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 }
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 這個區間是必須選擇的,所以我...