1. 程式人生 > >ZOJ-3872-Beauty of Array-思維

ZOJ-3872-Beauty of Array-思維

BE line problem post RR using beauty style can

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\n",sum); } return 0; }

ZOJ-3872-Beauty of Array-思維