Ultra-QuickSort树状数组
Vjudge
看数据范围很大,开数组会超内存,此题需要离散化
常见离散化
-
for(int i=1;i<=n;i++) { scanf("%lld",&v[i].v); v[i].id=i; } sort(v+1,v+1+n,cmpv); int cnt=1; for(int i=2;i<=n;i++) { if(v[i].v==v[i-1].v)v[i].v=cnt; else v[i].v=(++cnt); } v[1].v=1;//这里一定要放最后,否则会出错 sort(v+1,v+1+n,cmpid);
-
for(int i=1;i<=n;i++) { scanf("%lld",&v[i].v); a[i]=v[i].v; } sort(a+1,a+1+n); int size = unique(a + 1, a + 1 + n)-(a + 1); for(int i=1;i<=n;i++) { int t=lower_bound(a+1,a+1+n,v[i].v)-a; v[i].v=t; }
剩下的就比较简单了,倒着在相应的值位置存入1,表示已经存在,如果a[i]<a[j]&&i>j就存 在逆序对了
点击查看代码
#include <iostream> #include <cstdio> #include <algorithm> #include <math.h> #include <string.h> #include <string> #include <cstring> #include <vector> #include <map> #include <stack> #define int long long using namespace std; int n,a[500005],c[500005],N;//999999999 struct ac { int id,v; }v[500005]; bool cmpid(ac a,ac b) { return a.id<b.id; } bool cmpv(ac a,ac b) { return a.v<b.v; } int lowbit(int x) { return x&(-x); } void add(int x,int key) { while(x<=n) { c[x]+=key; x+=lowbit(x); } } int gs(int x) { int ans=0; while(x) { ans+=c[x]; x-=lowbit(x); } return ans; } signed main() { while(scanf("%lld",&n)!=EOF) { if(n==0)break; memset(c,0,sizeof(c)); memset(a,0,sizeof(a)); memset(v,0,sizeof(v)); for(int i=1;i<=n;i++) { scanf("%lld",&v[i].v); v[i].id=i;a[i]=v[i].v; } sort(a+1,a+1+n); int size = unique(a + 1, a + 1 + n)-(a + 1); for(int i=1;i<=n;i++) { int t=lower_bound(a+1,a+1+n,v[i].v)-a; v[i].v=t; // if(v[i].v==v[i-1].v)v[i].v=cnt; // else v[i].v=(++cnt); } // for(int i=1;i<=n;i++)cout<<v[i].v<<" "; // cout<<endl; int ans=0; for(int i=n;i>=1;i--) { ans+=gs(v[i].v); add(v[i].v+1,1); } cout<<ans<<endl; } return 0; }