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;
}