codeforces#1167F. Scalar Queries(树状数组+求贡献)

本文详细解析了Codeforces 1167F题目的解题思路,通过离散化处理和树状数组计算,求解特定数学问题。适用于算法竞赛准备和数据结构学习。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

题目链接:

https://codeforces.com/contest/1167/problem/F

题意:

给出长度为$n$的数组,初始每个元素为$a_i$

定义:$f(l, r)$为,重排$l$到$r$的元素,变成长度为$(r-l+1)$的数组$b_i$,$f(l, r)=\sum\limits_{i = 1}^{r - l + 1}{b_i \cdot i}$

求$\left(\sum\limits_{1 \le l \le r \le n}{f(l, r)}\right) \mod (10^9+7)$

数据范围:

$1 \le n \le 5 \cdot 10^5$

$1 \le a_i \le 10^9$

$a_i\neq a_j,for,i\neq j$

分析: 

把问题转化为求$a_i$对答案贡献的系数$x_i$

即:$ ans=x[1]\times a[1]+x[2]\times a[2]+x[3]\times a[3]+...$

只有$l\leq i\leq r$的时候,$a_i$才对答案有影响

如果$(l,r)$有$y$个数小于等于$a_i$,那么$x_i = x_i+y$

用树状数组计算$a_i$前面的数和后面的数对$x_i$的影响

ac代码:

#include<bits/stdc++.h>
#define  ll long long
#define pa pair<int,int>
using namespace std;
const int maxn=5e5+10;
const ll mod=1e9+7;
int n,t[maxn],num[maxn];
map<int,int>ma;
ll zz[maxn],tree[maxn];
void add(int x,int y)
{
    for(int i=x;i<=n;i+=(i&(-i)))tree[i]+=y;
}
ll quer(int x)
{
    ll res=0;
    for(int i=x;i;i-=(i&(-i)))res+=tree[i];
    return res;
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&num[i]);
        t[i]=num[i];
    }
    sort(t+1,t+n+1);//离散化处理
    for(int i=1;i<=n;i++)
        ma[t[i]]=i;
    for(int i=1;i<=n;i++)
    {
        zz[i]=quer(ma[num[i]])*(n-i+1)%mod;//前面的数对zz[i]的贡献
        add(ma[num[i]],i);
    }
    for(int i=1;i<=n;i++)
        tree[i]=0;
    for(int i=n;i>=1;i--)
    {
        zz[i]=(zz[i]+quer(ma[num[i]])*i%mod)%mod;//后面的数对zz[i]的贡献
        add(ma[num[i]],n-i+1);
        zz[i]=(zz[i]+(ll)(n-i+1)*i%mod)%mod;//num[i]对zz[i]的贡献
    }
    ll ans=0;
    for(int i=1;i<=n;i++)
        ans=(ans+(ll)num[i]*zz[i]%mod)%mod;
    printf("%lld\n",ans);
    return 0;
}

  

转载于:https://www.cnblogs.com/carcar/p/10877964.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值