FZU2018 fifth grade arithmetic operations m_sort (merge sort segment tree or seek reverse order)

  First, allow someone without ice less ice and less account login case the original model as the code and copy it directly to the naked plagiarism, and eventually was named outstanding job protested!

 

Subject to the effect:

  To an array containing a number n (1 <= n <= 5e5), requires the use of a bubble sort when increasing sequence, how many times a minimum number of exchanges.

 

Topic analysis:

  For any two of the array, if $ i <j $ and $ ai> aj $, the exchange so that it changes the order of ai and aj is bound, so only the number required to reverse.

  Share two methods, the first using a merge sort:

  For recursive partition of the array, and merge sort, merge process on both sides of the array, the first element of the array if the right, the left remaining elements are smaller than those of the element, it is possible to merge sort in the reverse order of the number of processes obtained.

  Share the following codes:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

const int maxn=5e5+5;
int arrcy[maxn],lef[maxn],rig[maxn];
ll ans=0;

void mergesort(int *,int ,int);
void merge(int *,int ,int,int);

int main ()
{
    int n,i;
    scanf("%d",&n);
    for (i=0;i<n;i++) scanf("%d",&arrcy[i]);
    mergesort(arrcy,0,n-1);
    printf("%lld\n",ans);
    return 0;
}

void mergesort(int arrcy[],int l,int r)
{
    if(l<r)
    {
        int m=(l+r)/2;
        mergesort(arrcy,l,m);
        mergesort(arrcy,m+1,r);
        merge(arrcy,l,m,r);
    }
    return ;
}

void merge(int arrcy[],int l,int m,int r)
{
    int num1=m-l+1,num2=r-m;
    int i,j;
    for (i=0;i<num1;i++) lef[i]=arrcy[l+i];
    for (i=0;i<num2;i++) rig[i]=arrcy[m+1+i];
    i=0,j=0;
    for (int k=0;k<r-l+1;k++)
    {
        if(i>=num1||(j<num2&&lef[i]<=rig[j]))
        {
            arrcy[l+k]=rig[j++];
        }
        else
        {
            if(num2>j)
                years + = num2- j;
            arrcy[l+k]=lef[i++];
        }
    }
}

  Method Two: Fenwick tree or tree line

  First discrete array sorted by size, from largest to smallest, its record for each element position, and then press the array element size from large to small, to its original position +1, the first calculation element 1 to the subsequent operating position and, that is, the number of reverse order of the elements, can be summed.

  Share tree line of code:

  

#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair <int,int> pii;
#define rep(i,x,y) for(int i=x;i<y;i++)
#define rept(i,x,y) for(int i=x;i<=y;i++)
#define pb push_back
#define fi first
#define se second
#define mp make_pair
#define dd(x) cout<<#x<<"="<<x<<" ";
#define de(x) cout<<#x<<"="<<x<<"\n";
#define mes(a,b) memset(a,b,sizeof a)

const int maxn=5e5+5;
pii arrcy[maxn];
class Tree
{
    public:
        int l,r;
        ll sum;
}tree[maxn<<2];

void build(int id,int l,int r);
void add(int id,int p,ll num);
ll query(int id,int l,int r);

bool comp(const pii &s1,const pii &s2)
{
    return s1.fi>s2.fi||(s1.fi==s2.fi&&s1.se>s2.se);
}

int main ()
{
    int n;
    scanf("%d",&n);
    REPT (i, 1 , n)
    {
        arrcy [i] .if = i;
        scanf("%d",&arrcy[i].fi);
    }
    build(1,1,n);
    ll ans=0;
    sort(arrcy+1,arrcy+1+n,comp);
    REPT (i, 1 , n)
    {
        years + query = ( 1 , 1 , arrcy [i] .se);
        add(1,arrcy[i].se,1);
    }
    printf("%lld\n",ans);
    return 0;
}
void build(int id,int l,int r)
{
    tree[id].l=l;
    tree[id].r=r;
    tree[id].sum=0;
    if(l==r) return ;
    int mid=(l+r)/2;
    build(id*2,l,mid);
    build(id*2+1,mid+1,r);
}
void add(int id,int p,ll num)
{
    if(tree[id].l>=p&&tree[id].r<=p)
    {
        tree[id].sum+=num;
        return ;
    }
    if(tree[id].l>p||tree[id].r<p) return ;
    if(tree[id*2].r>=p) add(id*2,p,num);
    if(tree[id*2+1].l<=p) add(id*2+1,p,num);
    tree[id].sum=tree[id*2].sum+tree[id*2+1].sum;    
}

ll query(int id,int l,int r)
{
    if(tree[id].l>=l&&tree[id].r<=r) return tree[id].sum;
    if(tree[id].l>r||tree[id].r<l) return 0;
    ll s=0;
    if(tree[id*2].r>=l) s+=query(id*2,l,r);
    if(tree[id*2+1].l<=r) s+=query(id*2+1,l,r);
    return s;
}

 

Guess you like

Origin www.cnblogs.com/FZUzyz/p/11723221.html