1. 程式人生 > >百練+重要逆序對+歸併時候計算記得標記一下位置便於之後統計再從標記處開始,減少掃描

百練+重要逆序對+歸併時候計算記得標記一下位置便於之後統計再從標記處開始,減少掃描

點選開啟連結
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string>
#include<cstring>
#include<string.h>
#include<math.h>
#include<algorithm>
#define inf 0x3f3f3f3f
#define LL long long
using namespace std;
int N=0;
const int maxn=2e5+5;
LL Arr[maxn]={0},temp[maxn]={0},sum=0;
void MergeSort(LL Arr[], int left,int mid, int right)
{
    int i=left,j=mid+1,len=right-left,flag=0,flag_vis=-1,index=0;
    while(i<=mid&&j<=right){
        if(Arr[i]>Arr[j]){
                if(flag_vis!=-1){
                    for(flag=flag_vis; flag<=mid; flag++){
                        if(Arr[flag]>2*Arr[j]){
                            sum+=mid-flag+1;
                            flag_vis=flag;
                            break;
                            }
                        }
                }
                else {
                    for(flag=i; flag<=mid;flag++){
                        if(Arr[flag]>2*Arr[j]){
                            sum+=mid-flag+1;
                            flag_vis=flag;
                            break;
                        }
                    }
                }
        temp[index++]=Arr[j]; j++;
        }
        else {
            temp[index++]=Arr[i]; i++;
        }
    }
    if(i>mid){
        while(j<=right){
            temp[index++]=Arr[j]; j++;
        }
    }
    else{
        while(i<=mid){
            temp[index++]=Arr[i];i++;
        }
    }
    for(int k=0;k<=len;k++){
        Arr[left+k]=temp[k];
    }
}
void Merge(LL Arr[], int left, int right)
{
    if(left<right){
        int mid=(left+right)/2;
        Merge(Arr,left,mid);
        Merge(Arr,mid+1,right);
        MergeSort(Arr,left,mid,right);
    }
}
int main()
{
    while(scanf("%d",&N)){
        if(N==0) break;
        for(int i=0;i<N;i++){
            scanf("%lld",&Arr[i]);
        }
        sum=0;
        Merge(Arr,0,N-1);
        printf("%lld\n",sum);
    }
return 0;
}

相關推薦

+重要+歸併時候計算記得標記一下位置便於之後統計標記開始減少掃描

點選開啟連結#include<iostream> #include<stdio.h> #include<stdlib.h> #include<string> #include<cstring> #include&l

- 歸併排序

題目連線:http://ybt.ssoier.cn:8088/problem_show.php?pid=1311 n開到1e5的話,硬剛肯定是要超時的,所以可以用歸併排序,並在排序的時候求出結果,其特點如下: 在每次合併兩個子陣列的時候,這兩個子陣列都已經是有序的啦 然後若a[i]>

18.12.20 DSA 重要

描述 給定N個數的序列a1,a2,...aN,定義一個數對(ai, aj)為“重要逆序對”的充要條件為 i < j 且 ai > 2aj。求給定序列中“重要逆序對”的個數。 輸入 第一行為序列中數字的個數N(1 ≤ N ≤ 200000)。第二行為序列a1, a2 ..

P1908 歸併排序分治

P1908 逆序對 題目連結 知識點補充: 劃分問題:把序列分成元素個數儘量相等的兩半 遞迴求解:把兩半元素分別排序 合併問題:把兩個有序表合併成一個 複雜度:nlogn 圖解: 前兩部分是很容易完成的,關鍵在於如何把兩個有序表合成一個,每次只需要把兩個序列的最小元素加以比較,刪除其中

P1908 歸併排序分治

P1908 逆序對 題目連結 知識點補充: 劃分問題:把序列分成元素個數儘量相等的兩半 遞迴求解:把兩半元素分別排序 合併問題:把兩個有序表合併成一個 複雜度:nlogn 圖解: 前兩部分是很容易完成

[隊內測試Day10.24Final]+表示式計算+貪心+圖論+數論?

T1 #include<cstring> #include<cstdio> #include<algorithm> #include<iostream> #include<map> #define L

MergeSort歸併排序和利用歸併排序計算出陣列中的

  首先先上LeetCode今天的每日一題(面試題51. 陣列中的逆序對):   在陣列中的兩個數字,如果前面一個數字大於後面的數字,則這兩個數字組成一個逆序對。輸入一個數組,求出這個陣列中的逆序對的總數。 //輸入: [7,5,6,4] //輸出: 5 示例1   由於題目中已經給出陣列長度為: 0

計蒜客 直線的交點(計算幾何 +

clas ret ons oid date pda 所有 efi define 題目鏈接 直線的交點 兩條直線的交點如果落在兩個平板之內的話 假設這兩條直線和兩條平板的交點橫坐標分別為 $x1, x2, X1, X2$ 那麽有$(x2 - x1)(X2 - X1)

[PHP] 算法-數組歸並排序並計算的個數的PHP實現

sep 可能 ret sort 輸入一個數 data UNC 總數 fun 在數組中的兩個數字,如果前面一個數字大於後面的數字,則這兩個數字組成一個逆序對。輸入一個數組,求出這個數組中的逆序對的總數P。並將P對1000000007取模的結果輸出。 即輸出P%1000000

的三種求法(歸併排序樹狀陣列線段樹)

求逆序對個數的三種方法 逆序對: 對於一個序列 $a_1$,$a_2$,$a_3$..$a_n$,如果存在$a_i$>$a_j$且i<j,則$a_i$和$a_j$為一個逆序對。 這裡將介紹3種求逆序對對數的方法。 在此之前,預設為你已經會了歸併排序,樹狀陣列和線段樹。(不會的可以百度學習一下)

演算法初級01——認識時間複雜度、對數器、 master公式計算時間複雜度、小和問題和問題

雖然以前學過,再次回顧還是有別樣的收穫~   認識時間複雜度 常數時間的操作:一個操作如果和資料量沒有關係,每次都是固定時間內完成的操作,叫做常數操作。 時間複雜度為一個演算法流程中,常數運算元量的指標。常用O(讀作big O)來表示。具體來說,在常數運算元量的表示式中,

【模板】歸併排序求

歸併排序求逆序對 1 #include <iostream> 2 #include <algorithm> 3 #include <cstring> 4 #include <cstdio> 5 6 typedef long lon

【模板】歸併排序(+求

沒有網址qwq 沒有oj 翻樹狀陣列看到求逆序對先複習一下歸併求逆序對qwq 逆序對真是個神奇的東西啊QAQ 純屬隨手一打隨手一貼quq 1 #include<cstdio> 2 #include<iostream> 3 using namespace std

洛谷P1908歸併排序求

#include<bits/stdc++.h> #define ll long long #define INF 0x3f3f3f3f using namespace std; int n,a[500010],c[500010]; ll ans=0; void msort(int b

【劍指offer】陣列中的(校正書上錯誤)【歸併排序】

題目描述 在陣列中的兩個數字,如果前面一個數字大於後面的數字,則這兩個數字組成一個逆序對。輸入一個數組,求出這個陣列中的逆序對的總數P。並將P對1000000007取模的結果輸出。 即輸出P%1000000007 題目保證輸入的陣列中沒有的相同的數字 資料範圍:

歸併排序,同步指標】陣列中的,兩個連結串列的第一個公共結點

面試題51:陣列中的逆序對 在陣列中的兩個數字如果前面一個數字大於後面的數字,則這兩個數字組成一個逆序對。輸入一個數組,求出這個陣列中的逆序對的總數。 分成長度1的子陣列,在合併之前統計相鄰子陣列之

歸併排序之神奇的

文章包含四部分 歸併排序的實現(略講) 歸併排序求逆序對 歸併排序例題詳講 樹狀陣列和歸併排序求逆序對的區別 關於歸併排序的實現 歸併排序主要分為兩大步: 1.分解 2.

個數的三種方法(歸併排序樹狀陣列權值線段樹)

求逆序對個數的三種方法 逆序對: 對於一個序列 a1a_1a1​,a2a_2a2​,a3a_3a3​…ana_nan​,如果存在aia_iai​>aja_jaj​且i<j,則aia_iai​和aja_jaj​為一個逆序對。 這裡將介紹3種求逆序對對數

歸併排序(求)

#include<bits/stdc++.h> using namespace std; void merge(int a[],int first,int mid,int last,int temp[]) { int i=first,j=mid+1; in

二分歸併 排序 求

題目:The Number of Inversions 題面: For a given sequence , the number of pairs  where  and , is called the number of inv