[BZOJ 5055]膜法师

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[BZOJ 5055]膜法师相关的知识,希望对你有一定的参考价值。

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]膜法师的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ_5055_膜法师_树状数组+离散化

bzoj5055 膜法师

[BZOJ 5055]膜法师

bzoj5055 膜法师

bzoj 5055: 膜法师——树桩数组

bzoj5055膜法师(离散化+树状数组)