2019牛客暑期多校训练营(第八场)

博客探讨了数组的美丽值概念,随着数组元素增加,如何计算美丽值的变化。文章通过实例解析了美丽值的增量公式,并指出在某些情况下,重复元素会减少总美丽值,需要维护一个sum来处理。此外,代码实现时遇到整数溢出问题,改为使用long long类型后得以解决。
摘要由CSDN通过智能技术生成

题目传送门

为了区分数组和区间,将{}表示数组,[]表示区间
为了简化描述,下面以bv表示beauty values(美丽值)
数组中的元素从1开始编号
{1}=>[1,1],bv=1
{1,2}=>[1,1],[2,2],[1,2],bv=4
{1,2,3}=>[1,1],[2,2],[3,3],[1,2],[2,3],[1,3],bv=10
{1,2,3,4}=>[1,1],[2,2],[3,3],[4,4],[1,2],[2,3],[3,4],[1,3],[2,4],[1,4],bv=20
……
那么,我们观察规律可发现,对于原数组,如果新增加一个不同于原数组任何一个数字的数字,它的美丽值增加的大小为i*(i+1)/2:

例如:对于数组{1,2,3},若增加一个4,即把他变为{1,2,3,4},那么显然,增加的子区间为[4,4],[3,4],[2,4],[1,4],bv=1×1+1×2+1×3+1×4=10,也就是4*(4+1)/2=10,所以,我们可以定义一个ans,储存全集,即ans=ans+i*(i+1);

全集的定义是:假设这个数字串中每一个数字都不相同的美丽值
那么,最终美丽值的结果=全集美丽值-重复美丽值

现在,对于集合{1,2}再增加一个1,即把它拓展为{1,2,1},则新增的区间为[3,3],[2,3],[1,3],这三个区间的美丽值分别为1,2,2,可以发现,索引值为1(从1开始编号)的元素1,对于区间[1,3]无贡献,所以最后的bv=ans+3*(3+1)/2-1=9

我们再看一个例子{2,3,4,5},对该数组新增一个数字3,即把他拓展为{2,3,4,5,3},那么,新增的区间为[5,5],[4,5],[3,5],[2,5],[1,5],美丽值分别为1,2,3,3,4,显然,第一个3在区间[2,5],[1,5]中无贡献,我们惊奇的发现,重复的美丽值刚好是重复元素的下标i,对于这个例子是2,上一个例子是1

我们再把这个结论稍微拓展一下,对于数组{1,2,1},我们再增加一个元素1,即原数组拓展为{1,2,1,1},那么,新增的子区间为[4,4],[3,4],[2,4],[1,4],美丽值分别为1,1,2,2,我们可以发现,索引值为3的1在新增的区间中出现3次,减去美丽值3,索引值为1的1在新增的区间中出现一次,减去美丽值1,所以,在这里,我们需要用一个sum将重复的美丽值进行维护,具体的实现方法如下(AC代码):

#include <iostream>
using namespace std;
typedef long long ll;
const int maxn = 100009;

ll a[maxn], n, h[maxn];

int main() {
	cin >> n;
	for (ll i = 1; i <= n; i++) {
		cin >> a[i];
	}
	ll sum = 0,ans=0;
	for (ll i = 1; i <= n; i++) {
		ans += i * (i + 1) / 2;//每增加一个不同的数字时,美丽值增加为i * (i + 1) / 2
		sum += h[a[i]];//如果增加的是一个与前面的数字相同的某个数,就要减去这个数的前一个位置,因为前一个位置对于美丽值不产生贡献
		ans -= sum;
		h[a[i]] = i;
	}
	cout << ans << endl;
	return 0;
}

注意这里有个坑点
当a[maxn]和h[maxn],n为int时通过率只有9.09%
我也不知道为什么,反正改为long long 就AC了,如果有大佬知道,还请不吝赐教!

标准题解是说用期望线性性?有时间我再回来填坑!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值