运用顺序进行,求每一个元素(包含其之前的所有元素)贡献

链接:https://ac.nowcoder.com/acm/contest/18428/C
来源:牛客网

Arup has to make many practice questions for his Computer Science 1 students. Since many of the questions deal with arrays, he has to generate arrays for his students. Since he doesn’t want to give them difficult practice problems, he always guarantees that the arrays (given to the students) have unique values. Namely, no value will appear twice in any of his arrays.

Unfortunately, Arup is too lazy to generate arrays! About 20 years ago when he started teaching Computer Science 1, he made one really long array to reuse but this long array may have duplicate values. When he makes problems, he simply grabs a contiguous subsequence of this long array to be the array to be used for a problem but he needs to make sure the contiguous subsequence does not contain duplicates. If the long array has terms a[0], a[1], …, a[n-1], a contiguous subsequence of the long array is any sequence of j-i+1 terms a[i], a[i+1], …, a[j] where 0 ≤ i ≤ j ≤ n – 1.

Given an array of n integers, determine how many contiguous subsequences of the array do not contain any repeated values. Note that two subsequences with the same contents are considered different (i.e., both counted in the total) if they start at different locations of the original long array.
输入描述:
The first input line contains a single positive integer, n (1 ≤ n ≤ 1e5), representing the size of the input array. The following line contains n space separated integers, representing the values of the
input array, in the order they appear in the array. Each of the array values will be an integer between 1 and 1e18, inclusive.

(Note: 1e5 means 1 times 10 to the fifth power, that is, 100000)
输出描述:
On a line by itself, output the total number of contiguous subsequences of the input array that do not contain any repeated values.
示例1
输入
复制
5
1 1 2 1 5
输出
复制
9
示例2
输入
复制
8
2 12 3 12 3 2 6 9
输出
复制
22
题解:从第一个数开始,求其本身以及包含之前所有数的贡献,最后将总贡献加起来。
先考虑没有重复数时,1 2 3 sum(含不同数子序列的和)=1(1)+2(2,1 2)+3(3,2 3,1 2 3);即每个不同位置的数的贡献为其位置索引(从一开始)
有重复数时,1 1 2 1 5,同样的思路,只不过标记重复数出现的位置,并将其所在位置索引减去,具体操作自己根据题意搞,标记时建议用map,数组标记容易段错误(注意题目所给空间)

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll nl=1e5+5;
map<ll,ll>v;//标记作用
ll a[nl];
int main(){
	ll n;
	cin>>n;
	ll i,j;
	for(i=0;i<n;i++){
		cin>>a[i];
	}
	ll sum=0;
	j=0;
	for(i=0;i<n;i++){
		if(v[a[i]]==0){//没有出现重复数
			sum+=i+1-j;
			v[a[i]]=i+1;
		}else{
			j=max(v[a[i]],j);//标记倒数第二次出现重复数的位置
			sum+=i+1-j;
			v[a[i]]=i+1;
		}
	}
	cout<<sum;
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值