POJ 2299 求逆序对个数 归并排序 Or数据结构

题意:
求逆序对个数 没有重复数字
线段树实现:
离散化。 单点修改,区间求和

// by SiriusRen
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
long long ans=0;
int n,t,f[2555555],sum[2555555],a[2555555];
bool cmp(int i,int j){return a[i]<a[j];}
void change(int l,int r,int pos){
    if(l==r){sum[pos]=1;return;}
    int mid=(l+r)>>1;
    if(mid<a[t])change(mid+1,r,pos<<1|1);
    else change(l,mid,pos<<1);
    sum[pos]=sum[pos<<1]+sum[pos<<1|1];
}
int query(int l,int r,int pos){
    if(l>a[t]&&r<=n)return sum[pos];
    int mid=(l+r)>>1;
    if(mid<=a[t])return query(mid+1,r,pos<<1|1);
    else return query(mid+1,r,pos<<1|1)+query(l,mid,pos<<1);
}
int main(){
    while(scanf("%d",&n)&&n){
        ans=0;
        memset(sum,0,sizeof(sum));
        for(int i=1;i<=n;i++)f[i]=i;
        for(int i=1;i<=n;i++)scanf("%d",&a[i]);
        sort(f+1,f+1+n,cmp);
        for(int i=1;i<=n;i++)a[f[i]]=i;
        for(t=1;t<=n;t++)change(1,n,1),ans+=query(1,n,1);   
        printf("%lld\n",ans);
    }
}

归并排序(掌握得不好,,,,以后还是用segtree吧。。。):

#include <cstdio>
#include <cstring>
#include <algorithm>
#define int long long
using namespace std;
int n,a[500005],q[500005],ans=0;
void solve(int l,int r){
    if(r==l)return;
    int mid=(l+r)/2;
    solve(l,mid);solve(mid+1,r);
    int jy1=l,jy2=mid+1,jy=l;
    while(jy1<=mid||jy2<=r){
        if(jy2>r ||(jy1<=mid&&a[jy1]<=a[jy2]))q[jy++]=a[jy1++];
        else{
            if(jy1<=mid) ans+=jy2-jy;
            q[jy++]=a[jy2++];
        }
    }
    for(int i=l;i<=r;i++)a[i]=q[i];
}
signed main(){
    while(scanf("%lld",&n)&&n){
        ans=0;
        for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
        solve(1,n);printf("%lld\n",ans);
    }
}
posted @ 2016-07-16 00:16  SiriusRen  阅读(149)  评论(0编辑  收藏  举报