• 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;
    }
  • 相关阅读:
    题解 P5996 【[PA2014]Muzeum】
    题解 CF1433G 【Reducing Delivery Cost】
    题解 CF1430E 【String Reversal】
    题解 CF710F 【String Set Queries】
    题解 P4334 【[COI2007] Policija】
    LIS 树状数组优化
    离散化模板
    P4309 [TJOI2013]最长上升子序列
    p3902 递增(incr)
    poj3417 暗的连锁
  • 原文地址:https://www.cnblogs.com/ckxkexing/p/8631894.html
Copyright © 2020-2023  润新知