XDU1024簡單逆序對(貪心||分治)

題目描述

逆序對問題對於你們來講已是很是熟悉的問題了,就是求i<j時,a[i] > a[j]的組數。如今請你求出一串數字中的逆序對的個數,須要注意的是,這些數字均在[0,9]以內。

輸入

第一行輸入T,表示有T組測試數據
對於每組數據,首先輸入n,表明有n個數(0<n<=10^6)
接下來輸入n個數,每一個數都在[0,9]以內

輸出

輸出逆序對的個數,且對10^9+7取模c++

樣例輸入

2
3
3 2 1
3
1 2 1

樣例輸出

3
1

解法一:數學貪心解法(有點小技巧哦)ide

#include<bits/stdc++.h>
using namespace std;
const int mod=1e9+7;
int d[10];
int main()
{
    int T,n;
    cin>>T;
    while(T--){
        cin>>n;
        int ans=0,arr[n];
        memset(d,0,sizeof(d));
        memset(arr,0,sizeof(arr));
        for(int i=1;i<=n;i++) cin>>arr[i];
        for(int i=1;i<=n;i++){
            int res=0;
            d[arr[i]]++;
            for(int j=arr[i]+1;j<=9;j++)
                res=(res+d[j])%mod;
            ans=(ans+res)%mod;
        }
        cout<<ans<<endl;
    } 
} 

解法二:分治(和歸併排序相似吧感受)測試

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
const int mod=1e9+7;
int ans;
int a[maxn],c[maxn];
void Conquer_Divide(int l,int r)
{
    int m=(l+r)/2;
    if(r>l){
        Conquer_Divide(l,m);
        Conquer_Divide(m+1,r);
        int i=l,j=m+1,t=l;
        while(i<=m&&j<=r){
            if(a[i]>a[j]){
                c[t++]=a[j++];
                ans=(ans+m-i+1)%mod;
            }
            else c[t++]=a[i++];
        }
        while(i<=m) c[t++]=a[i++];
        while(j<=r) c[t++]=a[j++];
        for(i=l;i<=r;i++) a[i]=c[i];
    }
}
int main()
{
    int n,T;
    cin>>T;
    while(T--){
        cin>>n;
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        ans=0;
        Conquer_Divide(1,n);
        printf("%d\n",ans);
    }
}
相關文章
相關標籤/搜索