POJ 2299 - Ultra-QuickSort BIT
題意
給我們一個(gè)序列 序列長度小于500000 每個(gè)元素 小于999999999 讓我們只移動(dòng)相鄰的元素
最終使得他們移動(dòng)到正好上升序的最小移動(dòng)次數(shù)
分析
我們看 最小的移動(dòng)次數(shù)其實(shí)是個(gè)幌子
因?yàn)槟阋苿?dòng)相鄰的元素 大的元素你不論如何移動(dòng)
就是要一個(gè)個(gè)移動(dòng)到所有比他小的元素的后面
來看原序列 9 1 0 5 4
對于9由于它是最大的 那么他就要慢慢移動(dòng)到最后一個(gè)
變成 1 0 5 4 9
那么此時(shí)可以忽略9 只看前面的元素 因?yàn)?已經(jīng)歸位
1 0 5 4 中 5 最大 那么換到最后 變成 1 0 4 5
有效序列變成 1 0 4
注意 我們在換的過程中 有沒有保證滿足最小交換次數(shù)?
我們移動(dòng)9 的時(shí)候 無論怎么移動(dòng) 都要保證9 最后在最后一個(gè)位置上
那么無論移動(dòng)后面的元素 還是移動(dòng)9 都是要么把后面的元素移動(dòng)到前面來
要么把9移動(dòng)到后面去 其實(shí)移動(dòng)9還是移動(dòng)后面元素 其實(shí)都可以看成一個(gè)方向改變序列
那么在只交換相鄰元素位置下的情況 其實(shí)沒有最小
我們求出來交換次數(shù) 就是最小 因?yàn)樗豢赡芸缭匾苿?dòng)
那么就是變成求逆序數(shù)問題了 每個(gè)元素前有幾個(gè)逆序 就要移動(dòng)幾次
當(dāng)然要離散化啦!
code
#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> using namespace std; typedef long long ll; const int lim = 500010; int c[lim],a[lim]; struct node{int x,id;// value and th }t[lim]; void add(int x,int val){while(x<lim){c[x]+=val;x+=x&(-x);} } ll sum(int x){ll ans = 0;while(x){ans+=c[x];x-=x&(-x); } return ans; } bool cmp(node a,node b){return a.x<b.x; } int main() {int n;while(scanf("%d",&n),n){for(int i=1;i<=n;i++)scanf("%d",&t[i].x),t[i].id = i;sort(t+1,t+1+n,cmp);for(int i=1;i<=n;i++)a[t[i].id] = i;ll s=0;for(int i=1;i<=n;i++){add(a[i],1);s+=max(i-sum(a[i]),1ll*0);//cout<<i-sum(a[i])<<endl; } printf("%lld\n",s); memset(c,0,sizeof(c)); }return 0; }如果數(shù)據(jù)中有重復(fù)元素
還可以這樣離散化
總結(jié)
以上是生活随笔為你收集整理的POJ 2299 - Ultra-QuickSort BIT的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 系列文章----.Net程序员学用Ora
- 下一篇: 作为IT从业者,你是如何做好个人职业规划