bzoj 3580 冒泡排序 亂搞+思維
阿新 • • 發佈:2018-04-09
亂搞 stdin mit bit long def 相對 cstring pen
Submit: 243 Solved: 108
[Submit][Status][Discuss]
1
k<=10^12
冒泡排序
Time Limit: 15 Sec Memory Limit: 256 MBSubmit: 243 Solved: 108
[Submit][Status][Discuss]
Description
下面是一段實現冒泡排序算法的C++代碼:
for (int i=1;i<n;i++)
for (int j=1;j<=n-i;j++)
if (a[j]>a[j+1])
swap(a[j],a[j+1]);
其中待排序的a數組是一個1~n的排列,swap函數將交換數組中對應位置的值。
對於給定的數組a以及給定的非負整數k,使用這段代碼執行了正好k次swap操作之後數組a中元素的值會是什麽樣的呢?
Input
輸入文件共2行。
第1行包含空格隔開的一個正整數n和一個非負整數k;
第2行包含n個空格隔開的互不相同的正整數,表示初始時a數組中的排列。
Output
輸出文件共1行。
若在執行完整個代碼之後執行swap的次數仍不夠k,那麽輸出一個字符串”Impossible!”(不含引號),否則按順序輸出執行swap操作k次之後數組a的每一個元素,用空格隔開。
Sample Input
1 11
Sample Output
Impossible!HINT
n<=10^6
k<=10^12
題解:這道題目的話,首先要去分析冒泡排序,設g[x]表示一個數前面比其大的個數,
那麽交換z次後,其前面比它大的個數絕對減少min(g[x],z),因為每一輪交換必定會交換下去一個比它大的數
所以可以二分出哪一輪。
然後二分出那一輪後
我們發現,g[i]<=x的話,那這個數一定排序完畢了。而對於g[i]>x的部分,他們相對於原數列的位置不變。
這樣就可以求出做了x次外層循環後的結果了
1 #include<cstring> 2 #include<iostream> 3 #include<algorithm> 4#include<cstdio> 5 #include<cmath> 6 7 #define ll long long 8 #define N 1000007 9 using namespace std; 10 inline ll read() 11 { 12 ll x=0,f=1;char ch=getchar(); 13 while(!isdigit(ch)){if(ch==‘-‘)f=-1;ch=getchar();} 14 while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-‘0‘;ch=getchar();} 15 return x*f; 16 } 17 18 int n;ll k; 19 int a[N],mx[N],b[N],fz[N]; 20 bool boo[N]; 21 int tree[N]; 22 23 inline int lowbit(int x){return x&(-x);} 24 int query(int x) 25 { 26 int res=0; 27 for (int i=x;i>=1;i-=lowbit(i)) 28 res+=tree[i]; 29 return res; 30 } 31 void add(int x) 32 { 33 for (int i=x;i<=n+1;i+=lowbit(i)) 34 tree[i]+=1; 35 } 36 ll calc(int x) 37 { 38 ll res=0; 39 for (int i=1;i<=n;i++) 40 res+=min(mx[i],x); 41 return res; 42 } 43 int main() 44 { 45 freopen("fzy.in","r",stdin); 46 freopen("fzy.out","w",stdout); 47 48 n=read(),k=read(); 49 for (int i=1;i<=n;i++) 50 a[i]=read(); 51 for (int i=1;i<=n;i++) 52 { 53 mx[i]=query(n+1)-query(a[i]); 54 add(a[i]); 55 } 56 int l=0,r=n; 57 while(l<r) 58 { 59 int mid=(l+r+1)>>1; 60 if (calc(mid)>=k) r=mid-1; 61 else l=mid; 62 } 63 if (l==n) 64 { 65 puts("Impossible!"); 66 return 0; 67 } 68 k-=calc(l);int num=0; 69 for (int i=1;i<=n;i++) 70 if (mx[i]>r) b[i-r]=a[i]; 71 else fz[++num]=a[i]; 72 sort(fz+1,fz+num+1); 73 num=0; 74 for (int i=1;i<=n;i++) 75 if (b[i]==0) b[i]=fz[++num]; 76 for (int i=1;i<n;i++) 77 if (b[i]>b[i+1]) 78 { 79 swap(b[i],b[i+1]); 80 k--;if (!k) break; 81 } 82 for (int i=1;i<=n;i++) 83 printf("%d ",b[i]); 84 }
bzoj 3580 冒泡排序 亂搞+思維