[BZOJ5055]膜法师
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[BZOJ5055]膜法师相关的知识,希望对你有一定的参考价值。
5055: 膜法师
Time Limit: 10 Sec Memory Limit: 128 MB Submit: 200 Solved: 102 [Submit][Status][Discuss]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 Input
样例1
4
1 2 3 4
样例二
10
6 8 4 1 3 0 7 5 9 2
4
1 2 3 4
样例二
10
6 8 4 1 3 0 7 5 9 2
Sample Output
样例输出1
50
样例输出2
1737
样例解释
对于样例 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
50
样例输出2
1737
样例解释
对于样例 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
先离散化再树状数组维护一下即可
#include <cstdio> #include <algorithm> using namespace std; typedef long long ll; const int maxn = 300000 + 10; const ll mod = 19260817; int n, a[maxn]; int ref[maxn], num[maxn], num_cnt; ll c1[maxn] = {0}, c2[maxn] = {0}; inline void Update(ll *arr, int pos, int val){ for(int i = pos; i <= n; i += i & -i) arr[i] = (arr[i] + val) % mod; } inline ll Query(ll *arr, int pos){ ll s = 0; for(int i = pos; i; i -= i & -i) s = (s + arr[i]) % mod; return s; } ll f[maxn], g[maxn]; int main(){ scanf("%d", &n); for(int i = 1; i <= n; i++){ scanf("%d", a + i); num[i] = a[i]; } sort(num + 1, num + n + 1); num_cnt = unique(num + 1, num + n + 1) - (num + 1); for(int t, i = 1; i <= n; i++){ t = lower_bound(num + 1, num + num_cnt + 1, a[i]) - num; ref[t] = a[i] % mod; a[i] = t; } for(int i = 1; i <= n; i++){ f[i] = Query(c1, a[i] - 1); Update(c1, a[i], ref[a[i]]); } for(int i = n; i; i--){ g[i] = Query(c2, n) - Query(c2, a[i]); if(g[i] < 0) g[i] += mod; Update(c2, a[i], ref[a[i]]); } ll ans = 0; for(int i = 1; i <= n; i++) ans = (ans + f[i] * g[i] % mod * ref[a[i]]) % mod; printf("%lld\n", ans); return 0; }
以上是关于[BZOJ5055]膜法师的主要内容,如果未能解决你的问题,请参考以下文章