1. 程式人生 > >[BZOJ 5055]膜法師

[BZOJ 5055]膜法師

return log using scan tchar nbsp algo std text

Description

在經歷過1e9次大型戰爭後的宇宙中現在還剩下n個完美維度, 現在來自多元宇宙的膜法師,想偷取其中的三個維度為偉大的長者續秒, 顯然,他能為長者所續的時間,為這三個維度上能量的乘積, 但目前的宇宙很不樂觀,胡亂偷取可能造成維度的崩潰, 所以,他必須按逆序偷取這些維度,且在偷取中, 每次偷取的維度的能量必須嚴格小於他上次偷取的能量, 由於膜法師生活在多元宇宙,所以他可以讓所有可能的偷取方案全部發生 但他數學不好,所以找到了你幫他求出能為長者續幾秒, 你要做的,就是在給定的維度序列a中, 求出所有滿足i<j<k且ai<aj<ak的ai*aj*ak的和
即 ∑ (a_i*a_j*a_k),要求 i<j<k 且 a_i<a_j<a_k

Input

第一行1個數 n 第二行n個數 a_i

Output

一個數,表示能為長者續幾秒,由於長者是不朽的, 所以能活很久,不妨將答案對**19260817**取模吧

Sample Input1

4
1 2 3 4

Sample Output1

50

Sample Input2

10
6 8 4 1 3 0 7 5 9 2

Sample Output2

1737

HINT

樣例解釋
對於樣例 1
有滿足條件的序列為
{1,2,3}——6
{1,2,4}——8
{1,3,4}——12
{2,3,4}——24
ans=6+8+12+24=50
數據範圍
30%的數據n<=300
60%的數據n<=3000
100%的數據n<=300000
0<=a[i]<=2147483647

題解

我們枚舉$j$很顯然答案就是

$$\sum _{j=1} ^n (a[j]*{\sum _{i=1} ^{j-1} a[i]}*{\sum _{k=j+1} ^{n} a[k]})$$

樹狀數組+離散亂搞就可以了。

emmmmmm(惡膜某民命秒沒)~

 1 //It is made by Awson on 2017.10.3
 2 #include <set>
 3 #include <map>
 4 #include <cmath>
 5 #include <ctime>
 6 #include <queue>
 7 #include <stack>
 8 #include <vector>
 9 #include <cstdio>
10 #include <string>
11 #include <cstring>
12 #include <cstdlib>
13 #include <iostream>
14 #include <algorithm>
15 #define LL long long
16 #define Max(a, b) ((a) > (b) ? (a) : (b))
17 #define Min(a, b) ((a) < (b) ? (a) : (b))
18 #define sqr(x) ((x)*(x))
19 #define lowbit(x) ((x)&(-(x)))
20 #define count COUNT
21 using namespace std;
22 const int N = 300000;
23 const LL MOD = 19260817;
24 void read(LL &x) {
25     char ch; bool flag = 0;
26     for (ch = getchar(); !isdigit(ch) && ((flag |= (ch == -)) || 1); ch = getchar());
27     for (x = 0; isdigit(ch); x = (x<<1)+(x<<3)+ch-48, ch = getchar());
28     x *= 1-2*flag;
29 }
30 
31 int n;
32 struct tt {
33     LL val;
34     int pos, rank;
35 }a[N+5];
36 LL sum[N+5], c[N+5], ans;
37 bool comp(const tt &a, const tt &b) {
38     return a.val < b.val;
39 }
40 bool accomp(const tt &a, const tt &b) {
41     return a.pos < b.pos;
42 }
43 
44 void add(int x, LL key) {
45     for (; x <= n; x += lowbit(x)) c[x] = (c[x]+key)%MOD;
46 }
47 LL count(int x) {
48     LL cnt = 0;
49     for (; x; x -= lowbit(x)) cnt = (cnt+c[x])%MOD;
50     return cnt;
51 }
52 void work() {
53     scanf("%d", &n);
54     for (int i = 1; i <= n; i++) {
55         read(a[i].val); a[i].pos = i;
56     }
57     sort(a+1, a+n+1, comp);
58     a[1].rank = 1;
59     for (int i = 2; i <= n; i++)
60         a[i].rank = a[i-1].rank+(a[i].val != a[i-1].val);
61     sort(a+1, a+n+1, accomp);
62     for (int i = 1; i <= n; i++) {
63         sum[i] = count(a[i].rank-1);
64         add(a[i].rank, a[i].val);
65     }
66     memset(c, 0, sizeof(c));
67     LL cnt = 0;
68     for (int i = n; i >= 1; i--) {
69         LL tmp = count(a[i].rank);
70         tmp = (cnt+MOD-tmp)%MOD;
71         ans = (ans+sum[i]*tmp%MOD*a[i].val)%MOD;
72         add(a[i].rank, a[i].val);
73         cnt = (cnt+a[i].val)%MOD;
74     }
75     printf("%lld\n", ans);
76 }
77 int main() {
78     work();
79     return 0;
80 }

[BZOJ 5055]膜法師