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);
}

原文地址:https://www.cnblogs.com/suika/p/9062665.html

时间: 2024-10-29 13:53:49

BZOJ_5055_膜法师_树状数组+离散化的相关文章

HDU 2227 Find the nondecreasing subsequences (DP+树状数组+离散化)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2227 Find the nondecreasing subsequences                                  Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)                                             

BZOJ 1227 [SDOI2009] 虔诚的墓主人 离线+树状数组+离散化

鸣谢:140142耐心讲解缕清了我的思路 题意:由于调这道题调的头昏脑涨,所以题意自己搜吧,懒得说. 方法:离线+树状数组+离散化 解析:首先深表本蒟蒻对出题人的敬(bi)意(shi).这道题简直丧心病狂,看完题后大脑一片空白,整个人都不好了,刚开始的思路是什么呢?暴力思想枚举每个墓碑,然后计算每个墓碑的虔诚度,然后再来统计.不过看看数据范围呢?10^9*10^9的矩阵,最多才10^5个树,光枚举就已经超时了,所以肯定不行.(不过要是考试真没思路我就那么搞了- -!) 然后也想到来枚举墓碑,不过

求逆序数模板(树状数组+离散化 || 归并排序法)

一篇不错的讲解:http://www.cnblogs.com/shenshuyang/archive/2012/07/14/2591859.html 代码如下:(树状数组+离散化) #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int maxn=500017; int n; int aa[maxn

Ultra-QuickSort (树状数组离散化)

题目原意是用归并排序,刚学树状数组,就用了下 树状数组的离散化 离散化,是数据范围太大是所借用的利器,举个例子,有四个数99999999 1 123 1583 数据范围太大,而树状数组中的c数组开的范围是数据的范围,这时候就需要离散化,把四个数一次标号为1 2 3 4(即第一个数,第二个数...),按键值排序之后 依次为2 3 4 1(即从小到大排序为第二个数,第三个数...),所以,第二个数是最小的,即f[2]=1,f[3]=2,f[4]=3,f[1]=4,也就是把键值变为了1~n,相对大小还

hdu4325 树状数组+离散化

http://acm.hdu.edu.cn/showproblem.php?pid=4325 Problem Description As is known to all, the blooming time and duration varies between different kinds of flowers. Now there is a garden planted full of flowers. The gardener wants to know how many flower

高桥低桥(树状数组离散化)

1335: 高桥和低桥 Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 362  Solved: 62 [Submit][Status][Web Board] Description 有个脑筋急转弯是这样的:有距离很近的一高一低两座桥,两次洪水之后高桥被淹了两次,低桥却只被淹了一次,为什么?答案是:因为低桥太低了,第一次洪水退去之后水位依然在低桥之上,所以不算"淹了两次".举例说明: 假定高桥和低桥的高度分别是5和2,初始水位为1 第一次

Ultra-QuickSort(树状数组 + 离散化)

Description In this problem, you have to analyze a particular sorting algorithm. The algorithm processes a sequence of n distinct integers by swapping two adjacent sequence elements until the sequence is sorted in ascending order. For the input seque

sdut2610---Boring Counting(离线+树状数组+离散化)

Boring Counting Time Limit: 3000ms Memory limit: 65536K 有疑问?点这里^_^ 题目描述 In this problem you are given a number sequence P consisting of N integer and Pi is the ith element in the sequence. Now you task is to answer a list of queries, for each query,

求逆序数数目(树状数组+离散化)

404在玩忍者印记(Mark of the Ninja)操纵忍者时遇到这样一个场景,两栋大楼之间有许多绳索,从侧面看,就像这个样子: 我们的忍者非常有好奇心,他可以观察到每个绳索的端点在两栋楼的高度,想知道这些绳索有多少个交点(图中黑色的点).他观察到不会建筑上不会有一点上有两个绳索,并且没有三条绳索共点. 输入描述 第一行:整数T,代表有T组数据. (1 <= T <= 100) 下一行:整数N,代表有N条绳索. (1 <= N <= 100000) 接下来Na行给出两个整数A_