zoukankan      html  css  js  c++  java
  • zoj 3872 Beauty of Array

    题意:

    求一个数组的所有连续子串中不同的数字的和。

    思路:

    考虑每一个数字对于最终结果的贡献。

    假设dp[i]表示以a[i]结尾的串的和,那么有dp[i] = dp[i-1] + a[i] * k。

    这里的k,如果当前的a[i]没有在前面出现过,那么对结果的贡献肯定是k = i次,因为以它结尾的字串有i个;

    但是如果出现过,假设它上一次出现的位置是pre,那么对结果的贡献就是k = i - pre喽。

    考虑串 1 2 3 2 3,当我考虑最后一个3的时候,以它为结尾的子序列有:

    1 2 3 2 3

    2 3 2 3

    3 2 3

    2 3

    3

    显然前3个序列中有两个3,所以在前三个序列中,3的贡献已经被前面的3给计算了,所以只有后两个序列才能算当前的3的贡献。

    代码:

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <algorithm>
     4 #include <map>
     5 using namespace std;
     6 typedef long long ll;
     7 const int N = 1e5 + 10;
     8 int a[N];
     9 ll dp[N];
    10 int main()
    11 {
    12     int t;
    13     scanf("%d",&t);
    14     while (t--)
    15     {
    16         memset(dp,0,sizeof(dp));
    17         map<int,int> mp;
    18         int n;
    19         scanf("%d",&n);
    20         for (int i = 1;i <= n;i++)
    21         {
    22             scanf("%d",&a[i]);
    23         }
    24         for (int i = 1;i <= n;i++)
    25         {
    26             dp[i] = dp[i-1] + (ll)(i-mp[a[i]]) * a[i];
    27             mp[a[i]] = i;
    28         }
    29         ll ans = 0;
    30         for (int i = 1;i <= n;i++) ans += dp[i];
    31         printf("%lld
    ",ans);
    32     }
    33     return 0;
    34 }
    35 /*
    36 3
    37 5
    38 1 2 3 4 5
    39 3
    40 2 3 3
    41 4
    42 2 3 3 2
    43 8*/
  • 相关阅读:
    git version info & svn version info map(七)
    /proc/pid/statm content analysis
    git log filter(六)
    git create remote branch (五)
    learning svn diff --summarize
    learning scala akka ask_pattern
    learning scala akka tell pattern(二)
    learning scala akka actorySystem create and close
    hibernate 自动生成数据库
    STRICT_TRANS_TABLES STRICT_ALL_TABLES
  • 原文地址:https://www.cnblogs.com/kickit/p/9000080.html
Copyright © 2011-2022 走看看