dp[i]=dp[i-1]+i-vis[num]
每向后移动一个点,就把上一个节点的子串补充一个数字,当移到最后一个节点的时候,把每一个节点的子串加在一起就是原串的所有子串。
当从后往前更新子串,第一次出现和补充的数字相同的数字时候,前面的子串都不在增加不同的数字数目。该节点往后的子串不同数字数目每一个加1.
代码
#include <stdio.h>
long long int dp[1000001], vis[1000001], a[1000001];
int main()
{
#ifdef ONLINE_JUDGE
#else
freopen("in.txt", "r", stdin);
#endif
int i, j, n;
long long int ans = 0;
scanf("%d", &n);
for (i = 1; i < n+1; i++)
{
scanf("%d", &a[i]);
}
dp[1] = 1, vis[a[1]] = 1;
for (i = 2; i < n + 1; i++)
{
dp[i] = dp[i - 1] + i - vis[a[i]];
vis[a[i]] = i;
}
for (i = 1; i < n + 1; i++)
{
ans += dp[i];
}
printf("%lld\n", ans);
return 0;
}
----------学习他人代码。