前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Codeforces 1167F(计算贡献)

Codeforces 1167F(计算贡献)

作者头像
ACM算法日常
发布2019-06-17 16:28:41
4040
发布2019-06-17 16:28:41
举报
文章被收录于专栏:ACM算法日常ACM算法日常

选题失误,这不是很好翻译,但自己看比较容易看懂吧~

## 要点

* 容易想到排序,然后对于每个数:

* 人的惯性思维做法是:$a[i]*(rank1的+rank2的+…)$。然而解法巧妙之处在于直接把所有的加和当成一个系数,然后先假装所有情况系数都是1,接着往上加,树状数组记录着所有之前比它小的数的情况,只有这些小的数也同时存在的区间才会增大它的系数。而且只在乎数量,不关注具体方案。

代码语言:javascript
复制
const int maxn = 5e5 + 5;
const int mod = 1e9 + 7;
int n, pos[maxn];
ll a[maxn];
ll ans;

struct FenwickTree {
    ll F[maxn], T[maxn];

    void Update1(int x, ll val) {
        for (; x <= n; x += x&-x)
            F[x] += val, F[x] %= mod;
    }

    ll Query1(int x) {
        ll res = 0;
        for (; x; x -= x&-x)
            res += F[x], res %= mod;
        return res;
    }

    void Update2(int x, ll val) {
        for (; x; x -= x&-x)
            T[x] += val, T[x] %= mod;
    }

    ll Query2(int x) {
        ll res = 0;
        for (; x <= n; x += x&-x)
            res += T[x], T[x] %= mod;
        return res;
    }
}bit;

int main() {
    read(n);
    rep(i, 1, n)    read(a[i]), pos[i] = i;
    sort(pos + 1, pos + 1 + n, [](int x, int y) { return a[x] < a[y]; });
    rep(i, 1, n) {
        int p = pos[i];
        //至少系数也得是1吧
        ans += a[p] * p % mod * (n - p + 1) % mod; ans %= mod;
        //然而有比自己小的,把系数挤得大于1
        ans += a[p] * (bit.Query1(p - 1) * (n - p + 1) % mod + bit.Query2(p + 1) * p % mod) % mod; ans %= mod;
        bit.Update1(p, p), bit.Update2(p, n - p + 1);
    }
    writeln(ans);
    return 0;
}
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-06-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 ACM算法日常 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档