Ultra-QuickSort poj-2299

来源:互联网 发布:淘宝开店宝软件 编辑:程序博客网 时间:2024/05/20 09:05

原题:POJ-2299


这个题目是一个求逆序数的题目

可以用树状数组、线段树、归并排序来做


树状数组、线段树只要先求和再更行就行了,插入法。在做的时候先要对序列进行离散,不然数字太大了


归并排序的做法是在合并的时候求逆序,假如有序列A和序列B,当Ai<Bi时,那么Bi的逆序数为 (length(A)-i+1),然后一次求逆序数再加起来就行了


以下代码是渣渣手写的,应该很容易看懂QAQ,结果sum要定义为 long long !


树状数组:

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;struct data{  int d,t;}p[500050];int cmp1(data a,data b){   return a.d<b.d;}int cmp2(data a,data b){   return a.t<b.t;}int c[500050];void updata(int x,int v,int n){    for(int i=x;i<n+10;i+=(i&(-i)))       c[i]+=v;}int getsum(int x){   int sum=0;   for(int i=x;i>0;i-=(i&(-i)))    sum+=c[i];   return sum;}int main() {    //freopen("C:\\Users\\adminjust\\Desktop\\test.txt","w",stdout);    int n;    while(cin>>n&&n){        for(int i=1;i<=n;i++)         {             scanf("%d",&p[i].d);             p[i].t=i;         }         sort(p+1,p+n+1,cmp1);         for(int i=1;i<=n;i++)            p[i].d=i;         sort(p+1,p+n+1,cmp2);         long long sum=0;         memset(c,0,sizeof(c));         for(int i=1;i<=n;i++){           sum+=(i-1-getsum(p[i].d));           updata(p[i].d,1,n);         }         cout<<sum<<endl;    }    return 0;}

线段树:

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;struct data {    int d,t;} p[500050];struct node {    int l,r,v;} q[50005000];int cmp1(data a,data b) {    return a.d<b.d;}int cmp2(data a,data b) {    return a.t<b.t;}int c[50005000];void build(int t,int l,int r) {    if(l==r) {        c[t]=0;        return ;    }    int mid=(l+r)/2;    build(t*2,l,mid);    build(t*2+1,mid+1,r);    c[t]=0;}void updata(int t,int x,int l,int r) {    c[t]++;    if(l==r&&l==x)        return ;    int mid=(l+r)/2;    if(x<=mid)        updata(t*2,x,l,mid);    else        updata(t*2+1,x,mid+1,r);}int getsum(int l,int r,int L,int R,int t) {    if(l<=L&&r>=R)        return c[t];    int mid=(L+R)/2;    if(r<=mid)        return getsum(l,r,L,mid,t*2);    else if(l>mid)        return getsum(l,r,mid+1,R,t*2+1);    else return getsum(l,mid,L,mid,t*2)+getsum(mid+1,r,mid+1,R,t*2+1);}int main() {    //freopen("C:\\Users\\adminjust\\Desktop\\test.txt","w",stdout);    int n;    while(cin>>n&&n) {        for(int i=1; i<=n; i++) {            scanf("%d",&p[i].d);            p[i].t=i;        }        sort(p+1,p+n+1,cmp1);        for(int i=1; i<=n; i++)            p[i].d=i;        sort(p+1,p+n+1,cmp2);        long long sum=0;        memset(c,0,sizeof(c));        build(1,1,n);        for(int i=1; i<=n; i++) {            sum+=(i-1-getsum(1,p[i].d,1,n,1));            updata(1,p[i].d,1,n);        }        cout<<sum<<endl;    }    return 0;}

归并:

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;int c[500050];long long sum;void lianjie(int l,int r,int L,int R) {    int *temp=new int[R+l+10];    int i,j,p;    for(i=l,j=L,p=0; i<=r&&j<=R; p++) {        if(c[i]>c[j]) {            sum+=(r-i+1);            temp[p]=c[j++];        } else temp[p]=c[i++];    }    while(i<=r)temp[p++]=c[i++];    while(j<=R)temp[p++]=c[j++];    for(int k=l; k<=R; k++)        c[k]=temp[k-l];}void MergeSort(int l,int r) {    if(l==r)        return ;    int mid=(l+r)/2;    MergeSort(l,mid);    MergeSort(mid+1,r);    lianjie(l,mid,mid+1,r);}int main() {  //  freopen("C:\\Users\\adminjust\\Desktop\\test.txt","w",stdout);    int n;    while(cin>>n&&n) {        for(int i=1; i<=n; i++)            scanf("%d",&c[i]);        sum=0;        MergeSort(1,n);        cout<<sum<<endl;    }    return 0;}






0 0
原创粉丝点击