hdu Minimum Inversion Number(線段樹求逆序數有關問題的一個小歸納)
Minimum Inversion Number
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 4904 Accepted Submission(s): 2991
Problem Description 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
Author CHEN, Gaoli
Source
Recommend Ignatius.L 首先,求逆序數對的思路: 1.得到整個數列後,從前往後掃,統計比a[i]小的,在a[i]後面的有多少個 這樣做的話,應該是隻有n2的暴力作法,沒想到更好的方法 2.統計a[i]前面的,且比它大的數 這樣做的話,就可以利用輸入的時效性,每輸入一個數,就把這個數的num[i]值加1, 然後統計比這個數大的數的num和, 因為這裡的和一定是在這個數列中比a[i]大,且在它前面出現的數之和, 然後把把這個和加到總逆序數sum裡。 這樣做的話直接的暴力作法依然是n2,但是, 我們可以在,統計
#include <stdio.h> #include <algorithm> using namespace std; int a[5005]; struct Node{ int l,r,num; }tree[50000]; void Build(int n,int x,int y){ tree[n].l = x; tree[n].r = y; tree[n].num = 0; if(x == y){ return; } int mid = (x + y) / 2; Build(2*n,x,mid); Build(2*n+1,mid+1,y); } void Modify(int n,int x){ int l = tree[n].l; int r = tree[n].r; int mid = (l + r) / 2; if(x == l && x == r){ tree[n].num = 1; return; } if(x <= mid) Modify(2*n,x); else Modify(2*n+1,x); tree[n].num = tree[2*n].num + tree[2*n+1].num; } int Query(int n,int x,int y){ int l = tree[n].l; int r = tree[n].r; int mid = (l + r) / 2; int ans = 0;; if(x == l && y == r) return tree[n].num; if(x <= mid) ans += Query(2*n,x,min(mid,y)); if(y > mid) ans += Query(2*n+1,max(mid+1,x),y); return ans; } int main(){ int n,sum,ans; int i,j; while(scanf("%d",&n) != EOF){ sum = 0; Build(1,0,n); for(i = 1;i <= n;i++){ scanf("%d",&a[i]); Modify(1,a[i]); sum += Query(1,a[i]+1,n); } ans = sum; for(i = 1;i < n;i++){ sum = sum + (n - 1 - a[i]) - a[i]; if(sum < ans) ans = sum; } printf("%d\n",ans); } }
相關推薦
hdu Minimum Inversion Number(線段樹求逆序數有關問題的一個小歸納)
Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 4904
hdu1394 Minimum Inversion Number (線段樹求逆序數&&思維)
題目傳送門 Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s)
Minimum Inversion Number (線段樹解決逆序數問題)
Minimum Inversion Number 線段樹解決逆序數問題 The inversion number of a given number sequence a1, a2, …, an is the number of pairs (ai, aj) t
poj3264(線段樹求區間最大最小值)
簡單題,求區間最大值和最小值 #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define N 1000010 int n,a[N
【HDU】1394Minimum Inversion Number-(線段樹單點更新,求出逆序數)
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 25122 &n
CodeForces - 1093G:Multidimensional Queries (線段樹求K維最遠點距離)
題意:給定N個K維的點,Q次操作,或者修改點的座標;或者問[L,R]這些點中最遠的點。 思路:因為最後一定可以表示維+/-(x1-x2)+/-(y1-y2)+/-(z1-z2)..... 所以我們可以儲存到線段樹裡,每次求區間最大值和最小值即可。 注意到我們可以先確定一個點的正負號,所以時間和空間節省了
hdu 6273 Master of GCD(線段樹區間維護兩個最小值)
Hakase has n numbers in a line. At first, they are all equal to 1. Besides, Hakase is interested inprimes. She will choose a continuous su
hdu 1394(線段樹求逆序數)
題意描述:給你一個有0--n-1數字組成的序列,然後進行這樣的操作,每次將最前面一個元素放到最後面去會得到一個序列,那麼這樣就形成了n個序列,那麼每個序列都有一個逆序數,找出其中最小的一個輸出! 分析:其實只需求出一個序列的逆序數即可,一位第i+1個序列的逆序數為第i
Ultra-QuickSort (線段樹求逆序數+離散化)
+= build https sse nbsp != ble ultra for Ultra-QuickSort OpenJ_Bailian - 2299 In this problem, you have to analyze a particular sorting
POJ 2299 Ultra-QuickSort 線段樹+求逆序數+離散化
In this problem, you have to analyze a particular sorting algorithm. The algorithm processes a sequence of n distinct integers by swapping
hdu 1694 Minimum Inversion Number (樹狀陣列)
題目連結:哆啦A夢傳送門 題意:給你一串n個值,每個a[i] 範圍在 [ 0 , n-1 ] ,然後我們可以把序列的頭部移到尾部,這樣就有n中不同的序列,問:在這n條序列中逆序數最少的是多少? 題解:我們可以用樹狀陣列,具體看程式碼註釋。 樹狀陣列模板:樹狀陣列 #inclu
Minimum Inversion Number (單點更新 線段樹 )
Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 19112
hdu-1255(線段樹求面積並)模板
題目連結:傳送門 思路: (1)建立線段的資訊,每個線段儲存l到r的線段的x位置和y的起始點與終點。 建立線段樹的節點資訊,每個節點代表一個區間的資訊,x表示區間的橫座標的位置,l,r表示縱座標的範圍,flag表示是否標記過,cover表示線段的覆蓋次數。 (2)先將y的位置按照從小到大排序,再將邊按
1394.Minimum Inversion Number(HDU)
題意理解 給定一個長度N的全排列,對這樣的一個序列對應一個逆序數;現在每次將第一個數放到序列最後一位,形成一個新的序列,這個新序列也對應一個逆序數。求所有這些放法對應逆序數的最小值。逆序數定義:對於i<j,a[i]>a[j]。 問題分析 用樹狀陣列資料結構 轉一:問題分兩
hdu 2665 Kth number(劃分樹)
first con build 這一 cst second class stream tom Kth number Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Oth
HDU 4553 約會安排(線段樹區間合並+雙重標記)
stack 基本 pushd 一段 ret problem 代碼 () vector 題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=4553 題目大意:就是有三種操作: ①DS x,安排一段長度為x的空閑時間跟屌
HDU 1540 Tunnel Warfare(線段樹 區間合並)
tle def ons main logs tmp 區間合並 http 合並 題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1540 題意:n個村子,相鄰兩個村子初始都是聯通的,詢問經過一些操作後村子x最多和幾個村子聯通(包
hdu 5919--Sequence II(主席樹--求區間不同數個數+區間第k大)
positions minus -s ima date rst itl 主席樹 技術 題目鏈接 Problem Description Mr. Frog has an integer sequence of length n, which can be denot
hdu 6183 Color it (線段樹 動態開點)
appears sub TP data- PE class pri operation count Do you like painting? Little D doesn‘t like painting, especially messy color paintings.
HDU 1540 Tunnel Warfare(線段樹)
題意:一條線上的點,D x是破壞這個點,Q x是表示查詢以x所在的最長的連續的點的個數,R是恢復上一次破壞的點。 分析:還是最大連續區間的板題,不過就是變成了單個節點進行更新。直接套用板子稍微更改就好, #include<cstdio> #include<cstring&g