ZOJ-3872-Beauty of Array-思維
阿新 • • 發佈:2018-03-23
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-思維