[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
1 2 3 4
Sample Output1
50
Sample Input2
10
6 8 4 1 3 0 7 5 9 2
Sample Output2
1737HINT
样例解释对于样例 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]膜法师的主要内容,如果未能解决你的问题,请参考以下文章