Educational Codeforces Round 65 (Rated for Div. 2)F. Scalar Queries【树状数组】

F. Scalar Queries

time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

You are given an array a1,a2,…,ana1,a2,…,an. All aiai are pairwise distinct.

Let's define function f(l,r)f(l,r) as follows:

  • let's define array b1,b2,…,br−l+1b1,b2,…,br−l+1, where bi=al−1+ibi=al−1+i;
  • sort array bb in increasing order;
  • result of the function f(l,r)f(l,r) is ∑i=1r−l+1bi⋅i∑i=1r−l+1bi⋅i.

Calculate (∑1≤l≤r≤nf(l,r))mod(109+7)(∑1≤l≤r≤nf(l,r))mod(109+7), i.e. total sum of ff for all subsegments of aa modulo 109+7109+7.

Input

The first line contains one integer nn (1≤n≤5⋅1051≤n≤5⋅105) — the length of array aa.

The second line contains nn integers a1,a2,…,ana1,a2,…,an (1≤ai≤1091≤ai≤109, ai≠ajai≠aj for i≠ji≠j) — array aa.

Output

Print one integer — the total sum of ff for all subsegments of aa modulo 109+7109+7

Examples

input

Copy

4
5 2 4 7

output

Copy

167

input

Copy

3
123456789 214365879 987654321

output

Copy

582491518

Note

Description of the first example:

  • f(1,1)=5⋅1=5f(1,1)=5⋅1=5;
  • f(1,2)=2⋅1+5⋅2=12f(1,2)=2⋅1+5⋅2=12;
  • f(1,3)=2⋅1+4⋅2+5⋅3=25f(1,3)=2⋅1+4⋅2+5⋅3=25;
  • f(1,4)=2⋅1+4⋅2+5⋅3+7⋅4=53f(1,4)=2⋅1+4⋅2+5⋅3+7⋅4=53;
  • f(2,2)=2⋅1=2f(2,2)=2⋅1=2;
  • f(2,3)=2⋅1+4⋅2=10f(2,3)=2⋅1+4⋅2=10;
  • f(2,4)=2⋅1+4⋅2+7⋅3=31f(2,4)=2⋅1+4⋅2+7⋅3=31;
  • f(3,3)=4⋅1=4f(3,3)=4⋅1=4;
  • f(3,4)=4⋅1+7⋅2=18f(3,4)=4⋅1+7⋅2=18;
  • f(4,4)=7⋅1=7f(4,4)=7⋅1=7;

 

分析:显然最后的答案应该等于每个数乘上一个系数。

假如a[i]是最小的数,那么它的系数应该等于i*(n-i+1)。

如果在a[i]的前面有个比a[i]小的数a[j],那么a[j]对a[i]系数的贡献应该等于包含a[i]和a[j]的区间数量,即j*(n-i+1)。

如果在a[i]的前面有个比a[i]小的数a[j],同上,贡献等于i*(n-j+1)。

所以我们现在需要维护比a[i]小的数的信息,那么对a[i]权值排序,可以用树状数组实现。

在a[i]左边的比a[i]小的数是id<a[i]的数,在a[i]右边的比a[i]小的数是id>a[i]的数,所以开两个BIT维护两种情况就可以了。

#include <bits/stdc++.h>

using namespace std;

const int mod = 1e9 + 7;

struct BIT {
    int n;
    vector<int> v;

    BIT(int n) : n(n) {
        v.resize(n + 1);
    }

    void update(long long x, long long d) {
        while (x <= n) {
            v[x] += d;
            if (v[x] >= mod)v[x] -= mod;
            x += (x & -x);
        }
    }

    long long que(long long x) {
        long long res = 0;
        while (x > 0) {
            res += v[x];
            if (res >= mod)res -= mod;
            x -= (x & -x);
        }
        return res;
    }
};

struct node {
    long long w, id;

    bool friend operator<(node a, node b) {
        return a.w < b.w;
    }
} a[500004];

BIT l(500004), r(500004);

int main() {
    int n;
    cin >> n;
    for (int i = 0; i < n; ++i) {
        scanf("%lld", &a[i].w);
        a[i].id = i + 1;
    }
    sort(a, a + n);
    long long ans = 0;
    for (int i = 0; i < n; ++i) {
        long long sum = a[i].id * (n - a[i].id + 1) % mod;
        sum = (sum + l.que(a[i].id) * (n - a[i].id + 1) % mod) % mod;
        sum = (sum + (r.que(n) - r.que(a[i].id) + mod) % mod * a[i].id % mod) % mod;
        l.update(a[i].id, a[i].id);
        r.update(a[i].id, n - a[i].id + 1);
        ans = (ans + a[i].w * sum % mod) % mod;
    }
    cout << ans << endl;
}

 

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值