給你
n 個數組成的序列,需要支援兩種操作
我們將序列分成n−
−√塊,每塊中維護原來的順序的值,以及將該塊所有值排序後的值,並且每個值還帶有乙個指標指向對應的那個值
修改整塊的就直接打標記,兩邊的暴力重構該塊
我們可以二分乙個答案(思考一下,二分出來的答案會不會序列中不存在呢?)
然後轉化成判定性問題,判斷二分出來的答案是不是在第
k 大
只需要對於每個塊,找該塊中小於這個值的個數,全部加起來看是不是k−
1,然後逼近答案。
證明一下這樣為什麼不會出現不存在的答案
假設正確答案是
s ,那麼二分出大於
s的答案顯然不可能,因為個數一定要加上
s 本身這乙個
小於等於
s,都有可能等於k−
1 ,然而二分出來的答案是這些值中的最大值(自己想為什麼)
所以二分出來的一定是
s
#include
#include
#include
#include
#include
#include
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fod(i,a,b) for(i=a;i>=b;i--)
#define mo 1000000007
using
namespace
std;
int pl[500],wz[80605],n,m,size;
struct note
a[80605],b[80605];
bool cmp(note x,note y)
int pd(int l,int r,int k)
if (nt(l)>r)
int main()
j=1;
wz[j]=1;
while (j+size<=n+1)
if(j!=n+1) sort(b+j,b+n+1,cmp);
fo(i,1,n)
cin>>m;
int i1=0;
fo(i,1,m)
int q;
if (nt(l)>r)
else
}else
if (pd(l,r,y)==k-1) printf("%d\n",y);
else
printf("%d\n",x); }}
}
查詢第K小數
查詢乙個陣列的第k小的數,注意同樣大小算一樣大。如 2 1 3 4 5 2 第三小數為3。輸入描述 輸入有多組資料。每組輸入n,然後輸入n個整數 1 n 1000 再輸入k。輸出描述 輸出第k小的整數。輸入例子 6 2 1 3 5 2 2 3 輸出例子 3 import j a.util.array...
HNOI模擬 K小數查詢
用什麼 一眼看上去就像乙個資料結構,但是好像很複雜。看看能幹什麼先!能支援區間找名次,支援修改。不知道treap可不可以做,不過區間維護名詞好像不行吧。發現範圍十分的小,分塊 好。怎麼做 對每一塊排乙個序,維護乙個加號的標記就可以了。include include include include i...
BUPT 查詢第K小數
查詢乙個陣列的第k小的數,注意同樣大小算一樣大。如 2 1 3 4 5 2 第三小數為3。輸入有多組資料。每組輸入n,然後輸入n個整數 1 n 1000 再輸入k。輸出第k小的整數。示例1 複製6 2 1 3 5 2 2 3複製 3題解 利用雜湊表排除重複數 include include usin...