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

Posted suika

tags:

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

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 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

先把权值离散化。
直接正反两次树状数组求小于等于x的和然后乘在一起即可。
 
代码:
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define N 300050
#define mod 19260817
typedef long long ll;
int n;
struct A {
    int num,v,id;
}a[N];
bool cmp1(const A &x,const A &y) {return x.num<y.num;}
bool cmp2(const A &x,const A &y) {return x.id<y.id;}
struct Bit {
    ll c[N];
    void fix(int x,ll v) {
        for(;x<=n;x+=x&(-x)) (c[x]+=v)%=mod;
    }
    ll inq(int x) {
        ll re=0;
        for(;x;x-=x&(-x)) (re+=c[x])%=mod;
        return re;
    }
}A,B;
ll L[N],R[N];
int main() {
    scanf("%d",&n);
    int i;
    for(i=1;i<=n;i++) scanf("%d",&a[i].num),a[i].id=i;
    sort(a+1,a+n+1,cmp1);
    int j=0; a[0].num=-3356456;
    for(i=1;i<=n;i++) {
        if(a[i].num!=a[i-1].num) j++;
        a[i].v=j;
    }
    sort(a+1,a+n+1,cmp2);
    for(i=1;i<=n;i++) {
        L[i]=A.inq(a[i].v-1);
        A.fix(a[i].v,a[i].num);
    }
    ll ans=0,sum=0;
    for(i=n;i>=1;i--) {
        R[i]=(sum-B.inq(a[i].v)+mod)%mod;
        B.fix(a[i].v,a[i].num);
        (sum+=a[i].num)%=mod;
        ans=(ans+L[i]*R[i]%mod*a[i].num%mod)%mod;
    }
    printf("%lld\n",ans);
}

 

以上是关于BZOJ_5055_膜法师_树状数组+离散化的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ5055: 膜法师

bzoj5055: 膜法师(BIT)

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

[BZOJ5055]膜法师

BZOJ5055: 膜法师

bzoj5055 膜法师