离散化

对于这种题:

给定n个数,如果一个数出现x次,则对答案的贡献为x^2,求这n个数对答案的贡献是多少。

n<=100000。

简单来说:

1 2 2        1^1+2^2 = 5

1 2 2 2 3         1 3 1 = 11

那么如果开一个数组来真正存这些你要平方的这些数,那这中间会有很多的“空档”,占内存不说,代码看起来还繁琐,所以用离散化来优化的话效果就很不错。

f[i]  i这个数字出现了几次
cin>>n;
for (int i=1; i<=n; i++) cin>>A[i];

... 离散化  
    for (int i=1; i<=n; i++) {t[i].x=A[i]; t[i].y=i;}
    sort(t+1,t+n+1,cmp);
    for (int i=1; i<=n; i++) while (!A[t[i].y]==t[i].x);
    A[t[i].y] 一定等于 t[i].x
    for (int i=1; i<=n; i++)
    {
        if (i==1 || t[i].x!=t[i-1].x) now++;
        A[t[i].y]=now;
    }

以上这个代码就是处理对于输入进去的数来标号和对重复的数进行覆盖的。

简而言之:

1 3 100000 3

当你输入以上这几个数时,

程序帮你把他们离散成以下这几个数据,这样就既把3到100000的中间的999997个数的空间省略,又不会改变他们的相对大小,那么操作起来就会更容易:

1 2 3 2

g[1]=1 g[2]=3 g[3]=100000

所以g数组的下标代表离散化变成的数据,数组指向的数就是原本的数。

原文地址:https://www.cnblogs.com/Zhoier-Zxy/p/8421435.html