日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Inverse Pair

發布時間:2023/12/3 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Inverse Pair 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Inverse Pair

題意:

一個數組a,現在構造一個數組c,c[i]=a[i]+0/1(0或1),使得c的逆序對最少

題解:

如果x在x+1的后面,我們讓x這個數+1,x+1不變,就可以讓逆序對少1。如果x在x+1后面,我們就認為連邊(x+1,x),x也有可能與x-1連邊,形成一個長度為L的鏈,那減少的逆序對數量就是L/2

代碼:

//還是自己菜最后還是看了網上模板才寫出來的#include <bits/stdc++.h>#define LL long long using namespace std;const int N=3e6+10; LL num[N],a[N]; LL ans; void Merge(int l,int mid,int r) //分治的治 合并是求逆序對的關鍵 {int i=l,j=mid+1,k=l;while(i<=mid&&j<=r){if(num[i]>num[j]) //前半部分中比num[i]大的數都比num[j]大,將num[j]放在num[i]前面的話,逆序數要加上mid+1-i{a[k++]=num[j++];ans+=mid-i+1; //統計逆序對}else //這里這情況不產生逆序對a[k++]=num[i++];}while(i<=mid)a[k++]=num[i++];while(j<=r)a[k++]=num[j++];for(int e=l;e<=r;e++) //將這次操作完的num數組更新num[e]=a[e]; }void Merge_sort(int l,int r) //分治的分 在這里不斷地把一個串細分然后回溯合并 {if(l<r){int mid=(l+r)/2;Merge_sort(l,mid);Merge_sort(mid+1,r);Merge(l,mid,r);} } int vis[N]; int main() {int n;cin>>n;int tot=0;for(int i=0;i<n;i++){cin>>num[i];if(vis[num[i]+1]){tot++;}else vis[num[i]]=1;}ans=0;Merge_sort(0,n-1); //cout<<ans<<endl;cout<<ans-tot;return 0; } /* 8 8 1 6 3 4 5 2 7 */

總結

以上是生活随笔為你收集整理的Inverse Pair的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。