http://poj.org/problem?id=1804 (题目链接)
题意
求逆序对
Solution1
归并排序。
每次合并时计算逆序对。
代码1
// poj1804 #include<algorithm> #include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> #include<cmath> #define LL long long #define inf 2147483640 #define Pi acos(-1.0) #define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout); using namespace std; inline LL getint() { int f,x=0;char ch=getchar(); while (ch<='0' || ch>'9') {if (ch=='-') f=-1;else f=1;ch=getchar();} while (ch>='0' && ch<='9') {x=x*10+ch-'0';ch=getchar();} return x*f; } const int maxn=1010; int a[maxn],tmp[maxn],ans,n; void solve(int l,int r) { if (l<r) { int mid=(l+r)>>1; solve(l,mid); solve(mid+1,r); int i=l,j=mid+1,k=l; while (i<=mid && j<=r) { if (a[i]>a[j]) {tmp[k++]=a[j++];ans+=mid-i+1;} else tmp[k++]=a[i++]; } while (i<=mid) tmp[k++]=a[i++]; while (j<=r) tmp[k++]=a[j++]; for (int i=l;i<=r;i++) a[i]=tmp[i]; } } int main() { int T,tt=0;scanf("%d",&T); while (T--) { scanf("%d",&n); for (int i=1;i<=n;i++) scanf("%d",&a[i]); ans=0; solve(1,n); printf("Scenario #%d: %d ",++tt,ans); } return 0; }
Solution2
树状数组。
代码2
// poj1804 #include<algorithm> #include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> #include<cmath> #define LL long long #define inf 2147483640 #define MOD 998244353 #define Pi acos(-1.0) #define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout); using namespace std; inline LL getint() { int f,x=0;char ch=getchar(); while (ch<='0' || ch>'9') {if (ch=='-') f=-1;else f=1;ch=getchar();} while (ch>='0' && ch<='9') {x=x*10+ch-'0';ch=getchar();} return x*f; } const int maxn=1010; int a[maxn],b[maxn],c[maxn],n,m; int lowbit(int x) {return x&-x;} void add(int x) { for (int i=x;i<=m;i+=lowbit(i)) c[i]++; } int query(int x) { LL res=0; for (int i=x;i;i-=lowbit(i)) res+=c[i]; return res; } int main() { int T,tt=0;scanf("%d",&T); while (T--) { scanf("%d",&n); for (int i=1;i<=n;i++) scanf("%d",&a[i]),b[i]=a[i]; sort(b+1,b+1+n); m=unique(b+1,b+1+n)-b-1; for (int i=1;i<=n;i++) a[i]=lower_bound(b+1,b+1+m,a[i])-b; for (int i=1;i<=m;i++) c[i]=0; LL ans=0; for (int i=n;i>=1;i--) { add(a[i]); ans+=query(a[i]-1); } printf("Scenario #%d: %lld ",++tt,ans); } return 0; }