离散化
离散化:
对于一组数:
1 2 3 6 15 … 999
如果我们要用 bool[] 型数组去标记他们,如下
1 1 1 0 0 1 0 0 0 0 0 0 0 0 1 ……..1
如果我们定义个结构体
struct node { int v; int sub; };
struct node p[50000];
p[0].sub = 1; p[0].v = 1;
p[1].sub = 2; p[1].v = 2;
p[2].sub = 3; p[2].v = 3;
p[3].sub = 4; p[3].v = 6;
…
为什么这样做,不能直接开一个数组?
a[1]=1 a[2]=2 a[3]=3 a[4]=6 a[5]=15 a[6]=999
#include <iostream> #include <stdio.h> #include <stdlib.h> #include <algorithm> #include <string.h> using namespace std; const int maxn=500005; int n; int aa[maxn]; //离散化后的数组 int tree[maxn]; //树状数组 struct Node { int v; int sub; }in[maxn]; int lowbit(int x) { return x&(-x); } void update(int t,int value) { for(int i=t;i<=n;i+=lowbit(i)) { tree[i] += value; } } int getsum(int x) { int sum=0; for(int i=x;i>=1;i-=lowbit(i)) { sum+=tree[i]; } return sum; } bool cmp(Node a ,Node b) { return a.v < b.v; } int main() { while(scanf("%d",&n) && n) { //离散化 for(int i = 1; i <= n; i++) { scanf("%d",&in[i].v); in[i].sub=i; } sort(in+1,in+n+1,cmp); for(int i = 1; i <= n; i++) { aa[in[i].sub] = i; } //树状数组求逆序 memset(tree, 0, sizeof(tree)); long long ans = 0; for(int i = 1; i <= n; i++) { update(aa[i], 1); ans += i-getsum(aa[i]); } cout<<ans<<endl; } return 0; }