这道题目数据很水,按照题目给的数据范围来说,用冒泡排序肯定会超时,然而用冒泡排序用时只有93ms,但是用线段树来解题的话只有31ms
解题思路:
看到这道题的时候,感觉和冒泡排序很像,但是算一下时间复杂度却会超时,那么我们可以用冒泡的思想来解题,看过这几个样例之后,可以发现这么一个规律:一个数必然与在它前面比它大的数字进行交换,根据这个规律,建立线段树点更新,区间查询,从左往右依次读入数据,比如数字k,先在线段树中查询k+1~n这个范围内的数字个数,再将k加入线段树,即可求解,这个方法在面对数据量比较大的情况下是比较有优势的
You want to processe a sequence of n distinct integers by swapping two adjacent sequence elements until the sequence is sorted in ascending order. Then how many times it need.
For example, 1 2 3 5 4, we only need one operation : swap 5 and 4.
3 1 2 3 4 4 3 2 1
0 6
#include<stdio.h> #include<string.h> #define maxn 1005 int tree[maxn*4],ans; void update(int i,int pos,int left,int right); void query(int i,int ql,int qr,int left,int right); void pushup(int i); int main() { int n; while(scanf("%d",&n)!=EOF) { memset(tree,0,sizeof(tree)); ans=0; for(int i=0;i<n;i++) { int a; scanf("%d",&a); if(a!=n) query(1,a+1,n,1,n); update(1,a,1,n); } printf("%d\n",ans); }
return 0; } void update(int i,int pos,int left,int right) { if(pos==left&&pos==right) { tree[i]=1; return ; } int mid=(left+right)>>1; if(pos<=mid) update(i<<1,pos,left,mid); else update(i<<1|1,pos,mid+1,right); pushup(i); } void query(int i,int ql,int qr,int left,int right) { if(ql<=left&&qr>=right) { ans+=tree[i]; return; } int mid=(left+right)>>1; if(ql<=mid)
query(i<<1,ql,qr,left,mid); if(qr>=mid+1) query(i<<1|1,ql,qr,mid+1,right); } void pushup(int i) { tree[i]=tree[i<<1]+tree[i<<1|1]; }