題意
注:本文的**中的輸出不嚴格正確,反正loj的資料也沒多強,不會pe。如果後面加強了當我沒說
沒錯,第乙個還是我的做法。
記得是哪年的scp還是noip初賽竟然程式題就是這個思路,然後我照搬了。
我們這道題目反著考慮,它讓我們加數,我們就刪除數字,從後往前刪除數字,我們先建乙個排好序的鍊錶,然後從中乙個個刪除數字,然後通過鍊錶來跳,由於每次最多刪除兩個數字,除2就是乙個,所以鍊錶每次最多跳一次,時間複雜度:o(n
logn
)o(nlogn)
o(nlog
n)。當然有一種情況要特殊考慮一下,就是當n=2
n=2n=
2時刪除到了中位數的位置,這種情況要處理一下,其他也就沒什麼了。
#include
#include
#include
#define n 11000
using
namespace std;
struct ****
a[n]
;inline
bool
cmp(**** x,**** y)
struct node
b[n]
;void
del(
int x)
int n,be[n]
;int list[n]
,top;
intmain()
sort
(a+1
,a+n+
1,cmp)
;for
(int i=
1;i<=n;i++
)be[a[i]
.y]=i,b[i]
.x=a[i]
.x;//確定其在鍊錶中的位置
int ans=n/2+
1,l=n/
2/*左邊有多少個數字*/
,r=n/
2/*右邊有多少個數字*/
;for
(int i=n;i>=
1;i--
)//按順序刪除
else
if(l>r)
list[
++top]
=b[ans]
.x;}
if(be[i]
==ans)
//剛好卡在中位數的位置
if(be[i]
>ans)r--
;else l--
;del
(be[i]);
}//後面就是輸出的問題了。
printf
("%d %d\n"
,t,n/2+
1);int now=0;
for(
int i=top;i>=
1;i--
)printf
("%d"
,list[i]);
if(now!=10)
printf
(" ");
}printf
("\n");
}return0;
}
搞兩個堆,然後不斷插入,如果siz
esize
size
之差≥ 2≥2
≥2了,時間複雜度:o(n
logn
)o(nlogn)
o(nlog
n)。(當然,兩個堆的做法也可以有其他實現方法(例如像做法1一樣,等到奇數再調節,而且最多調節一次),但本質上都是通過兩個堆求中間的數字。)
時間複雜度:o(n
logn
)o(nlogn)
o(nlog
n)
#include
#include
#include
#include
#include
#include
using
namespace std;
struct cmp1};
priority_queue <
int,vector<
int>
, cmp1> q1,kong1;
priority_queue <
int> q2,kong2;
void
init()
while
(q1.
size()
>q2.
size()
+1)}
if(i&1)
}puts(""
);}}
intmain()
838/
我們考慮用線段樹來找到中位數是哪個,對於第i
ii次而言,我們就是要找到i2+
1\frac+1
2i+
1大的陣列,那麼能不能讓這個這麼大的數字自動找上門來呢?
我們先讓t[i
]=i2
+1
t[i]=\frac+1
t[i]=2
i+1
我們排序一遍,然後從小到大看,如果這個數字x
xx原本就是在第i
ii次及之前插入的,我們就把t[i
]−
−t[i]--
t[i]−−
,如果t[i
]=
0t[i]=0
t[i]=0
了,那麼這個就是中位數。
不難發現,如果乙個數字是第i
ii次插入的話,那麼t[i
]t[i]
t[i]
~t [n
]t[n]
t[n]
都要減一。
那麼我們只要用線段樹管理t
tt陣列不就行了嗎?
但是怎麼處理t[i
]=
0t[i]=0
t[i]=0
的情況呢?
我們暴力儲存正數最小值,當正數最小值等於0
00時就暴力進入這個區域重複此操作,把為0
00的數拿出來同時更新最小值。
時間複雜度:對於管理[l,
r]
[l,r]
[l,r
]區間的節點,他最多有r−l
+1
r-l+1
r−l+
1次進入機會,所以全部節點的範圍加起來,就是o(n
logn
)o(nlogn)
o(nlog
n)啦。當然,這也能解決每一次插入求的不是中位數,而是第k
kk大的題目。
當然,由於這道題目只是當奇數的時候再查詢,所以可以處理一下減少常數,嫌麻煩也可以直接全部偶數設為inf,這樣也沒有多大問題。
沒有**。
平衡樹他不香嗎。(求i2+
1\frac+1
2i+
1大值)
時間複雜度:o(n
logn
)o(nlogn)
o(nlog
n)
動態中位數
178.動態中位數 統計描述 提交自定義測試 題目描述 輸入n個32位有符號整數,當已輸入的個數為奇數個時,輸出此時的中位數。輸入描述 第一行乙個整數n 第二行n個32位有符號整數。輸出描述 輸出一行,n 2 上取整 個中位數,中間用空格隔開。對於 40 資料 n 1000 對於所有資料 n 100...
動態中位數
依次讀入乙個整數序列,每當已經讀入的整數個數為奇數時,輸出已讀入的整數構成的序列的中位數。輸入格式 第一行輸入乙個整數p,代表後面資料集的個數,接下來若干行輸入各個資料集。每個資料集的第一行首先輸入乙個代表資料集的編號的整數。然後輸入乙個整數m,代表資料集中包含資料的個數,m一定為奇數,資料之間用空...
動態中位數
include include include include define fir i,a,b for int i a i b i using namespace std priority queue,greater q1,kong1 priority queueq2,kong2 void ini...