題解 CQOI2009 中位數

2022-05-05 19:39:12 字數 1454 閱讀 3264

目錄分析

注意事項

code

執行限制:時間不超過 \(1.00\ \textrm\),空間不超過 \(128\ \textrm\)。

給出 \(1,2,\cdots,n\) 的乙個排列,統計該排列有多少個長度為奇數的連續子串行的中位數是 \(b\)。中位數是指把所有元素從小到大排列後,位於中間的數。

第一行為兩個正整數 \(n\) 和 \(b\),第二行為 \(1,2,\cdots,n\) 的排列。

輸出乙個整數,即中位數為 \(b\) 的連續子串行個數。

插一句題外話,這道題與 csp-s2019 d1t2 有異曲同工之妙。

列舉所有連續子串行,暴力排序找中位數。

複雜度:\(\mathcal(n^3\log n)\)

我們觀察一下這種子串行的條件:

根據排序的定義,可以將後面這個條件轉換成「若連續子串行的長度為 \(t\),則 \(b\) 是第 \(\left\lceil\dfrac\right\rceil\) 大,也就是說比 \(b\) 大的數與比 \(b\) 小的數數量相同」。

這樣,我們只需要遍歷左端點在 \(b\) 及其左邊,右端點在 \(b\) 及其右邊的連續子串行,用字首和處理出比 \(b\) 大和比 \(b\) 小的數的數量。

複雜度:\(\mathcal(n^2)\)。

想到了 \(60\) 分做法,\(100\) 分也簡單了。

預處理出比 \(b\) 大的數的數量減去比 \(b\) 小的數的數量的值。如果有兩個字首和和相等,就有乙個這樣的數列。

易證這個值一定在 \([-n,n]\) 的範圍內,用乙個陣列 \(cnt_i\) 記錄下值為 \(i\) 的字首和的數量。

處理 \(b\) 左邊時,將左邊的字首和統計進去。處理右邊時,計算字首和 \(s_i\) 並讓 \(ans\leftarrow ans+cnt_\)。

這樣就能在 \(\mathcal(n)\) 的時間內完成了。

如果你統計左邊的字首和時從前往後統計的,計算右邊的答案時 \(s_i\) 就得是正的,否則 \(s_i\) 就得是負的,同時右邊的字首和就得從 \(b\) 開始統計。

#include using namespace std;

constexpr int max_n = 100000;

int a[max_n], cnt[max_n*2+1]; // 原陣列+數量統計

int main()

cnt[max_n]++, tmp = 0;

for (int i = pos - 1; i >= 0; i--) // 統計左邊的字首和

tmp = 0, ans += cnt[max_n];

for (int i = pos + 1; i < n; i++) // 計算答案

printf("%d\n", ans);

return 0; // 然後就 ac 了、

}

CQOI2009 中位數 字首和

給出1 n的乙個排列,統計該排列有多少個長度為奇數的連續子串行的中位數是b。中位數是指把所有元素從小到大排列後,位於中間的數。輸入格式 第一行為兩個正整數n和b,第二行為1 n的排列。資料規模 對於30 的資料中,滿足n 100 對於60 的資料中,滿足n 1000 對於100 的資料中,滿足n 1...

洛谷P1627 CQOI2009 中位數

給出1 n的乙個排列,統計該排列有多少個長度為奇數的連續子串行的中位數是b。中位數是指把所有元素從小到大排列後,位於中間的數。第一行為兩個正整數n和b,第二行為1 n的排列。資料規模 對於30 的資料中,滿足n 100 對於60 的資料中,滿足n 1000 對於100 的資料中,滿足n 100000...

CQOI2009 葉子的染色

首先,選擇任意乙個度數大於 1 的節點為根的最優的答案都是固定的,具體證明這裡不加贅述。我們仔細研究,他只要求根節點到葉子節點的最後乙個有色節點的顏色。我們對第 x 號節點染色,意味著我們把所有它子樹中的葉子節點最近的乙個有色節點的顏色就發生了改變。顯然,兒子越多的節點價效比越高。因此,我們定義 d...