zoukankan      html  css  js  c++  java
  • ZOJ-3872-Beauty of Array-思维

    ZOJ-3872-Beauty of Array

    传送门:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3872

    参考:https://blog.csdn.net/u013050857/article/details/45285515

    题意:

    定义Beauty数是一个序列里所有不相同的数的和,求一个序列所有子序列的Beauty和

      1 <= N <= 100000

    【解题思路】由于数据比较大,常规方法求子序列和肯定是行不通的,我们不妨这样想:

      因为要区别不同的数,可以看成序列里的数是一个一个加进去的,每次加入一个数,统计前面序列里第一次出现新加入的这个数的序列的dp(就是找到前面最近的相同数,从这个位子后面开始计算),

      注意到每次多的x,一定是在所在序列独一无二的,不然相当于没有加上,考虑完独一无二,再考虑重复的,只用加上前一项的dp即可。

    举个例子:

    1 2 3 1

    定义dp(当前元素前面(包括自己)所有包含自己的子序列的和)

    定义sum(当前元素前面所有子序列的和,包括此元素)

    //输入   1     2     3          1

    //dp      1     5     14    14+3

    //sum   1     6      20    37

    //a[i]      1     2      3   

    理解了思路,代码很容易实现,也是比较短,精髓都在for循环里,因为只用了一个for循环,每次新加入一个元素,就可以求出当前所有子序列的Beauty和,所以复杂度为O(n).

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    const int maxn = 100009;
    int a[maxn];
    
    int main(){
        int t;
        scanf("%d",&t);
        while(t--)
        {
            int n;
            scanf("%d",&n);
            memset(a,0,sizeof(a));
            long long dp=0,sum=0;
            for(int i=1;i<=n;i++)
            {
                int x;
                scanf("%d",&x);
                dp+=(i-a[x])*x;
                sum+=dp;
                a[x]=i;
            }
            printf("%lld
    ",sum);
        }
        return 0;
    }
  • 相关阅读:
    爬虫示例
    S20_DAY23--课堂笔记
    python--常用模块之正则
    S20_DAY22--课堂笔记
    win10系统重装
    CCF 命令行选项
    CCF 任务调度
    CCF 出现次数最多的数
    CCF ISBN
    CCF 最大的矩形
  • 原文地址:https://www.cnblogs.com/ckxkexing/p/8631894.html
Copyright © 2011-2022 走看看