离散化

对于这种题:

给定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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值