bzoj5055 膜法师

Posted

tags:

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

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

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
先离散
枚举中间点,找到所有符合条件的i,k
对于枚举的j,对答案贡献a[j]∑ika[i]a[k]
就等于a[j]*(∑ia[i]*∑ka[k])
维护两个线段树,每次求出和,再将a值加入
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 typedef long long ll;
 7 int Mod=19260817;
 8 int n,sz;
 9 ll ans,sum1[300001],sum2[300001],has[300001],a[300001],b[300001];
10 ll c[1200001][3];
11 void pushup(int rt,int p)
12 {
13     c[rt][p]=(c[rt*2][p]+c[rt*2+1][p])%Mod;
14 }
15 void update(int rt,int l,int r,int x,ll d,int p)
16 {
17     if (l==r)
18     {
19         c[rt][p]+=d;
20         c[rt][p]%=Mod;
21         return;
22     }
23     int mid=(l+r)/2;
24     if (x<=mid) update(rt*2,l,mid,x,d,p);
25     else update(rt*2+1,mid+1,r,x,d,p);
26     pushup(rt,p);
27 }
28 ll query(int rt,int l,int r,int L,int R,int p)
29 {
30     if (l>=L&&r<=R)
31     {
32         return c[rt][p];
33     }
34     int mid=(l+r)/2;
35     ll s=0;
36     if (L<=mid) s+=query(rt*2,l,mid,L,R,p);
37     s%=Mod;
38     if (R>mid) s+=query(rt*2+1,mid+1,r,L,R,p);
39     s%=Mod;
40     return s;
41 }
42 int main()
43 {
44     int i;
45     cin>>n;
46     for (i=1; i<=n; i++)
47     {
48         scanf("%lld",&a[i]);
49         b[i]=a[i];
50     }
51     sort(b+1,b+n+1);
52     sz=unique(b+1,b+n+1)-(b+1);
53     for (i=1; i<=n; i++)
54     {
55         ll x=a[i];
56         a[i]=lower_bound(b+1,b+sz+1,a[i])-b;
57         has[a[i]]=x%Mod;
58     }
59     for (i=1; i<=n; i++)
60     {
61         if (a[i]-1>=1)
62             sum1[i]=query(1,1,sz,1,a[i]-1,1)%Mod;
63         update(1,1,sz,a[i],has[a[i]],1);
64     }
65     for (i=n; i>=1; i--)
66     {
67         if (a[i]+1<=sz)
68             sum2[i]=query(1,1,sz,a[i]+1,sz,2)%Mod;
69         update(1,1,sz,a[i],has[a[i]],2);
70     }
71     for (i=2; i<n; i++)
72     {
73         ans+=(has[a[i]]*sum1[i]%Mod)*sum2[i]%Mod;
74         ans%=Mod;
75     }
76     cout<<ans;
77 }

 

以上是关于bzoj5055 膜法师的主要内容,如果未能解决你的问题,请参考以下文章

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

bzoj5055 膜法师

[BZOJ 5055]膜法师

bzoj5055 膜法师

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

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