bzoj 3580 氣泡排序

2021-06-29 13:51:02 字數 1517 閱讀 7082

下面是一段實現氣泡排序演算法的c++**:

for (int i=1;ia[j+1])

swap(a[j],a[j+1]);

其中待排序的a陣列是乙個1~n的排列,swap函式將交換陣列中對應位置的值。

對於給定的陣列a以及給定的非負整數k,使用這段**執行了正好k次swap操作之後陣列a中元素的值會是什麼樣的呢?

輸入檔案共2行。

第1行包含空格隔開的乙個正整數n和乙個非負整數k;

第2行包含n個空格隔開的互不相同的正整數,表示初始時a陣列中的排列。

輸出檔案共1行。

若在執行完整個**之後執行swap的次數仍不夠k,那麼輸出乙個字串」impossible!」(不含引號),否則按順序輸出執行swap操作k次之後陣列a的每乙個元素,用空格隔開。

1 11impossible!

n<=10^6

k<=10^12

據說是清華集訓的題。。?【霧】

我們用upper[i]記錄給定陣列中i前面比i大的數的個數。然後二分外層迴圈做了幾次。若做了x次。則總次數=sigma(min(upper[i],x))

然後我們發現,upper[i]<=x的話,那這個數一定排序完畢了。而對於upper[i]>x的部分,他們相對於原數列的位置不變。這樣就可以求出做了x次外層迴圈後的結果了。

然後我們再模擬剩下的一次內層迴圈就可以了。

【果然我還是太弱。。。感謝ydc大大otl】

#include#includeusing namespace std;

int a[1000001],upper[1000001];

int ans[1000001],sa[1000001];

int tr[1000001];

int n;

inline int lowbit(int x)

inline void add(int x,int xx)

inline int sum(int x)

int main()

int l=1,r=n;

long long sx;

while(l<=r)

sx=0;

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

sx+=(long long)min(r+1,upper[i]);

long long m=k-sx;

if(m>0)

sx=0;

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

sx+=min(r,upper[i]);

m=k-sx;

int p=0;

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

}sort(sa+1,sa+1+p);

p=0;

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

}for(i=1;ians[i+1])

}for(i=1;i<=n-1;i++)

printf("%d ",ans[i]);

printf("%d\n",ans[i]);

return 0;

}

bzoj 5347 氣泡排序

考慮到最後a i 都要等於i,並且每個 a i i 的a i 一輪最多向前走一次,所以局數至少是 max。又因為對於a i i來說,一輪不動意味著 a i 1 a i 所以 i 1 a i 1 是 i a i 的,所以要麼該位置不是max的位置,要麼就會向前移動,所以局數正好就是 max啦。incl...

BZOJ 5416 Noi2018 氣泡排序

bzoj 5416 noi2018 氣泡排序 dp 組合數 樹狀陣列 好題。合法的排列的交換次數剛好是交換次數的下界,也就是說不能有多餘的交換。也就是對於ai這個數,只能從i到ai這乙個方向走。考慮x,y,z三個數 x y z y需要和x z各交換一次,這顯然不能使y這個數滿足只向乙個方向移動這個條...

氣泡排序 排序 氣泡排序

既然寫了計組思來想去便打算把資料結構也寫下來,寫的時候總是發現看的時候無法發現的問題,受益良多。交換排序的基本思想 exchange until sorted 順序,分支,迴圈 注意偽 的熟悉 下面介紹兩種交換演算法 首先進行聯想,用乙個圖進行輔助聯想 水冒泡過程 頂部是陣列的begin,底部理解為...