Beauty of Array

Beauty of Array

Edward has an array A with N integers. He defines the beauty of an array as the summation of all distinct integers in the array. Now Edward wants to know the summation of the beauty of all contiguous subarray of the array A.

Input

There are multiple test cases. The first line of input contains an integer T indicating the number of test cases. For each test case:

The first line contains an integer N (1 <= N <= 100000), which indicates the size of the array. The next line contains N positive integers separated by spaces. Every integer is no larger than 1000000.
Output

For each case, print the answer in one line.

Sample Input
3
5
1 2 3 4 5
3
2 3 3
4
2 3 3 2

Sample Output
105
21
38

题意:给出n个数字的序列,求所有连续的子序列中不同数字的和的和
例:2 3 3

连续的子序列 该子序列不同数字的和
2 2
2 3 5
2 3 3 5
3 3
3 3 3
3 3
最终结果 2+5+5+3+3+3=21

思路:找每个数对最终结果的贡献
包含a[i]的连续子序列有:
1.如果a[i]之前没出现过,就有(n-i)(i+1)个
2.如果a[i]之前出现过了,就有(n-i)
((i+1)-(vis[a[i]]+1))个
注:数组下标从0开始的

以下分析暂假设a[i]之前没出现过
子序列中要想有a[i]及a[i]之后的元素,一定会有a[i],也就是说对于a[i]及a[i]之前的每一个元素,都会用到(n-i)个a[i],从第一个元素的到a[i]一共有(i+1)个元素,
所以a[i]对最终结果的贡献就是 a[i](n-i)(i+1)

现在考虑a[i]之前出现过
对于a[i]上次出现的位置到a[i]现在的位置之间的元素,包含a[i]现在的位置,都会用到(n-i)个a[i],而 (vis[a[i]],i] 是((i+1)-(vis[a[i]]+1))个,
所以所以a[i]对最终结果的贡献就是 a[i](n-i)((i+1)-(vis[a[i]]+1))

乘号显示不出来,具体看代码吧

#include<cstdio>
#include<cstring>
using namespace std; 
typedef long long ll;
const int maxn=1e5+5;
ll a[maxn];
int vis[maxn];//这个元素最后出现的位置,如果是-1就是还没出现过
int main(){
	int T,n;
	scanf("%d",&T);
	while(T--){
		scanf("%d",&n);
		memset(vis,-1,sizeof(vis));
		for(int i=0;i<n;i++)
		scanf("%lld",&a[i]);
		ll sum=0;
		for(int i=0;i<n;i++){
			if(vis[a[i]]!=-1){  //a[i]在前面出现过了 
				sum+=a[i]*(n-i)*(i-vis[a[i]]);
				//也就是sum+=a[i]*(n-i)*((i+1)-(vis[a[i]]+1)) 
			}
			else{ //a[i]之前没出现过
				sum+=a[i]*(n-i)*(i+1);
			}
			vis[a[i]]=i;//更新a[i]最后出现的位置 
		}
		printf("%lld\n",sum); 
	}
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/qq_42936517/article/details/84620256