常用技巧:离散化
建树状空间或者线段表时,可能会出现占用空间过大的问题,这时可以考虑离散化的方法。
比如说我们只需要关注数之间的大小关系,而不必在意数具体的值时,就可以采用离散化的方法来进行处理。这种情况下,只需要将原数列中每个数替换为这个数在数列中的大小排名就可以。但是离散化只是一种思想,可以根据实际情况采用合适的数据结构和程序实现。以洛谷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; }


浙公网安备 33010602011771号