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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

Minimum Inversion Number HDU - 1394(权值线段树/树状数组)

發布時間:2023/12/15 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Minimum Inversion Number HDU - 1394(权值线段树/树状数组) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

The inversion number of a given number sequence a1, a2, …, an is the number of pairs (ai, aj) that satisfy i < j and ai > aj.

For a given sequence of numbers a1, a2, …, an, if we move the first m >= 0 numbers to the end of the seqence, we will obtain another sequence. There are totally n such sequences as the following:

a1, a2, …, an-1, an (where m = 0 - the initial seqence)
a2, a3, …, an, a1 (where m = 1)
a3, a4, …, an, a1, a2 (where m = 2)

an, a1, a2, …, an-1 (where m = n-1)

You are asked to write a program to find the minimum inversion number out of the above sequences.
Input
The input consists of a number of test cases. Each case consists of two lines: the first line contains a positive integer n (n <= 5000); the next line contains a permutation of the n integers from 0 to n-1.
Output
For each case, output the minimum inversion number on a single line.
Sample Input
10
1 3 6 9 0 8 5 7 4 2
Sample Output
16

挺惱火的一個題,wa了好幾次,還是不能很好地理解權值線段樹的一些比較深奧的東西。
題意就是不斷的把第一個元素放到最后一個位置上所形成的逆序對的個數,最少是多少。。
我們先求出初始序列的逆序對數。
在不斷的把起始元素放到最后一個位置上時,逆序對的改變是n-a[i]-a[i]-1。希望有大佬能告訴我這原理是什么,不明白到底為什么是醬紫。求逆序対用了兩種方式權值線段樹和樹狀數組。樹狀數組更快一點、
代碼如下:

#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #define ll long long using namespace std;const int maxx=5e3+100; struct node{int l;int r;int v; }p[maxx<<2]; int a[maxx],b[maxx]; int n;void pushup(int cur) {p[cur].v=p[cur<<1].v+p[cur<<1|1].v; } void build(int l,int r,int cur) {p[cur].l=l;p[cur].r=r;p[cur].v=0;if(l==r) return ;int mid=l+r>>1;build(l,mid,cur<<1);build(mid+1,r,cur<<1|1);pushup(cur); } void update(int pos,int cur,int add) {int L=p[cur].l;int R=p[cur].r;if(L==R){p[cur].v=1;return ;}int mid=L+R>>1;if(pos<=mid) update(pos,cur<<1,add);else update(pos,cur<<1|1,add);pushup(cur); } int query(int cur,int l,int r) {int L=p[cur].l;int R=p[cur].r;if(l<=L&&R<=r) return p[cur].v;int mid=L+R>>1;if(r<=mid) return query(cur<<1,l,r);else if(l>mid) return query(cur<<1|1,l,r);else return query(cur<<1,l,mid)+query(cur<<1|1,mid+1,r); } int main() {while(scanf("%d",&n)!=EOF){build(1,n,1);for(int i=1;i<=n;i++) scanf("%d",&a[i]);int ans=0;for(int i=1;i<=n;i++){b[i]=a[i]+1-query(1,1,a[i]+1)-1;ans+=b[i];update(a[i]+1,1,1);}int sum=ans;for(int i=1;i<=n;i++){sum+=n-a[i]-(a[i]+1);//!!!記住規律!!! ans=min(ans,sum);}printf("%d\n",ans);} }//11 2 4 5 8 1 6 3 10 9 11 7

樹狀數組

#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define ll long long using namespace std;const int maxx=5e3+100; int b[maxx],c[maxx]; struct node{int id;int v; }p[maxx]; int n; bool cmp(const node &a,const node &b) {return a.v<b.v; } bool cmp1(const node &a,const node &b) {return a.id<b.id; } int lowbit(int x){return x&-x;} void update(int cur) {while(cur<=2*n){c[cur]+=1;cur+=lowbit(cur);} } int query(int cur) {int ans=0;while(cur){ans+=c[cur];cur-=lowbit(cur);}return ans; } int main() {while(scanf("%d",&n)!=EOF){memset(c,0,sizeof(c));for(int i=1;i<=n;i++) scanf("%d",&p[i].v),p[i].id=i;sort(p+1,p+1+n,cmp);int ans=0;for(int i=1;i<=n;i++){b[i]=(i-query(p[i].id)-1);ans+=b[i];update(p[i].id);}int sum=ans;sort(p+1,p+1+n,cmp1);for(int i=1;i<n;i++){sum+=n-p[i].v-p[i].v-1;ans=min(ans,sum);}printf("%d\n",ans);}return 0; }

努力加油a啊,(o)/~

總結

以上是生活随笔為你收集整理的Minimum Inversion Number HDU - 1394(权值线段树/树状数组)的全部內容,希望文章能夠幫你解決所遇到的問題。

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