常用技巧:离散化

建树状空间或者线段表时,可能会出现占用空间过大的问题,这时可以考虑离散化的方法。

比如说我们只需要关注数之间的大小关系,而不必在意数具体的值时,就可以采用离散化的方法来进行处理。这种情况下,只需要将原数列中每个数替换为这个数在数列中的大小排名就可以。但是离散化只是一种思想,可以根据实际情况采用合适的数据结构和程序实现。以洛谷P1908的树状数组解法为例:

/*
  离散化+树状数组
*/
#include<bits/stdc++.h>
using namespace std;
int n,c[500005],num[500005];
struct node
{
    int val,loc;
}a[500005];

bool cmd(node A,node B)
{
    if(A.val==B.val){
        return A.loc>B.loc;
    }
    return A.val>B.val;
}
void add(int i,int k)
{
    while(i<=n){
        c[i]+=k;
        i+=i&(-i);
    }
}
int query(int i)
{
    long long res=0;
    while(i>0){
        res+=c[i];
        i-=i&(-i);
    }
    return res;
}

int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i].val);
        a[i].loc=i;
    }
    sort(a+1,a+n+1,cmd);
    for(int i=1;i<=n;i++){
        num[a[i].loc]=i;
    }
    long long ans=0;
    for(int i=1;i<=n;i++){
        add(num[i],1);
        ans+=query(num[i]-1);
    }
    printf("%lld\n",ans);
    return 0;
}

 

posted @ 2020-10-09 14:50  太山多桢  阅读(178)  评论(0)    收藏  举报