poj2299
归并排序

#include<cstdio> #include<cmath> #include<algorithm> #include<iostream> #include<cstring> #include<cstdlib> #define maxn 510000 using namespace std; long long n,a[maxn],ans,b[maxn]; long long read(){ long long x=0,f=1;char ch=getchar(); while (ch>'9' || ch<'0'){if (ch=='-') f=-1;ch=getchar();} while (ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } void merge(int l,int m,int r){ int i=l,j=m+1,k=i; while (i<=m && j<=r){ if (a[i]>a[j]){ ans+=m-i+1; b[k++]=a[j++]; } else b[k++]=a[i++]; } while (i<=m) b[k++]=a[i++]; while (j<=r) b[k++]=a[j++]; for (int w=l;w<=r;w++) a[w]=b[w]; } void merge_sort(int l,int r){ if (l<r){ int m=(l+r)>>1; merge_sort(l,m); merge_sort(m+1,r); merge(l,m,r); } } int main(){ while (1){ n=read(); if (n==0) return 0; ans=0; memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); for (int i=1;i<=n;i++) a[i]=read(); merge_sort(1,n); printf("%lld\n",ans); } }
树状数组

#include<cstdio> #include<cmath> #include<algorithm> #include<iostream> #include<cstring> #include<cstdlib> #define maxn 510000 #define ll long long using namespace std; struct node{ ll data,rank; }a[maxn]; ll n,k,b[maxn],cnt,sum[maxn]; bool cmp(node a,node b){ return a.data<=b.data; } ll lowbit(ll x){return x&(-x);} void update(ll x,ll d){ for (int i=x;i<=k;i+=lowbit(i)) sum[i]+=d; } ll getsum(ll x){ ll tmp=0; for (int i=x;i;i-=lowbit(i)) tmp+=sum[i]; return tmp; } int main(){ while (1){ scanf("%lld",&k); if (k==0) return 0; memset(sum,0,sizeof(sum)); ll ans=0,cnt=0;a[0].data=2100000000; for (int i=1;i<=k;i++){ scanf("%lld",&a[i].data); a[i].rank=i; } sort(a+1,a+k+1,cmp);//离散化 for (int i=1;i<=k;i++) b[a[i].rank]=a[i].data==a[i-1].data?cnt:++cnt; for (int i=1;i<=k;i++){ update(b[i],1); ans+=i-getsum(b[i]); } printf("%lld\n",ans); } }