https://www.xoj.red/contests/show/1231
下面会写一些题目的解析什么的,当然不会粘贴题目只是简单提一下
(部分题目简单的题目就不概括了)
其实难度应该前面比较低.
本题求出冒泡排序需要几趟。
考虑一次冒泡排序的交换,减小对应1个位子上的1个逆序对。
但是对于每一个位子所需要减小的逆序对数量是不一样的。
对于每一趟,消去每一个位子上1个逆序对
所以趟数就是每个位子上的数产生逆序对数的最大值。
最后的+1指的是即使上一次已经消除所有逆序对了,我们并不知道数组有序了,所以判断最后一遍查看是否有序。
考虑树状数组维护$O(n log_2 n)$
和善的树状数组代码如下:
# include <bits/stdc++.h> using namespace std; const int N=1e5+10; int a[N],tmp[N],c[N]; int n,T; void update(int x){for (;x<=n;x+=x&-x)c[x]++;} int query(int x){int ret=0;for (;x;x-=x&-x) ret+=c[x];return ret;} int main() { scanf("%d",&n); tmp[0]=n; for (int i=1;i<=n;i++) scanf("%d",&a[i]),tmp[i]=a[i]; sort(tmp+1,tmp+tmp[0]+1); T=unique(tmp+1,tmp+1+tmp[0])-tmp-1; int ans=0; for (int i=1;i<=n;i++) { int w=lower_bound(tmp+1,tmp+1+T,a[i])-tmp; update(w); ans=max(i-query(w),ans); } printf("%d\n",ans+1); return 0; }