2018QBXT刷題遊記(18)
阿新 • • 發佈:2018-12-13
【2018QBXT刷題遊記】
Day4 TEST6
T3 game
【吐槽】這幾天寫了多少道game了!
【題目大意】長度為n的數列,第i次交換任意相鄰元素需要付出i的代價。操作完的序列的醜陋度是B*逆序對個數,其中B是給定的常數。求醜陋度和操作所付出的代價之和最小值。
【冷靜分析】繼續在紙上寫寫畫畫,突然想起逆序對個數就是相鄰交換恢復成有序序列的次數!所以只用統計出逆序對個數,判斷一下什麼時候i會大於b即可。
#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> using namespace std; #define ll long long const int MAXN=50005; ll b,a[MAXN],tmp[MAXN],sum,ans; int n; void Merge(int l,int mid,int r){ int i=l; int j=mid+1; int k=l; while(i<=mid&&j<=r){ if(a[i]>a[j]){ tmp[k++]=a[j++]; ans+=mid-i+1; } else tmp[k++]=a[i++]; } while(i<=mid)tmp[k++]=a[i++]; while(j<=r) tmp[k++]=a[j++]; for(int i=l;i<=r;i++) a[i]=tmp[i]; } ll S(int x){return (ll)(1+x)*x/2;} void Merge_sort(int l,int r){ if(l<r){ int mid=(l+r)>>1; Merge_sort(l,mid); Merge_sort(mid+1,r); Merge(l,mid,r); } } int main(){ freopen("game.in","r",stdin); freopen("game.out","w",stdout); scanf("%d%lld",&n,&b); for(int i=1;i<=n;i++) scanf("%lld",&a[i]); ans=0; Merge_sort(1,n); sum=b*ans; if(ans<=b){ sum=sum-ans*b+S(ans); } else{ sum=sum-b*b+S(b); } printf("%lld\n",sum); return 0; }