牛客练习赛8 B 储物点的距离(前缀和)

题目链接

题目描述
一个数轴,每一个储物点会有一些东西,同时它们之间存在距离。
每次给个区间[l,r],查询把这个区间内所有储物点的东西运到另外一个储物点的代价是多少?
比如储物点i有x个东西,要运到储物点j,代价为x * dist( i , j )
dist就是储物点间的距离。

输入描述:
第一行两个数表示n,m

第二行n-1个数,第i个数表示第i个储物点与第i+1个储物点的距离ai

第三行n个数,表示每个储物点的东西个数bi

之后m行每行三个数x l r

表示查询要把区间[l,r]储物点的物品全部运到储物点x的花费
每次查询独立
输出描述:
对于每个询问输出一个数表示答案
答案对1000000007取模
示例1
输入
复制
5 5
2 3 4 5
1 2 3 4 5
1 1 5
3 1 5
2 3 3
3 3 3
1 5 5
输出
复制
125
72
9
0
70
思路:一开始可能想不到怎么做,但是把式子列一下就可以看出来了,对于一个x,l,r来说答案显然是∑a【i】*|sum【x】-sum【i】|,其中sum【i】为1到点i的距离,拆开后我们就发现a【i】*sum【i】我们是可以预处理的,至于∑a【i】*sum【x】的话用cnt记录a【i】的前缀和就可以了,唯一的坑点就是取模,要格外小心。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2e5+5;
const ll mod=1e9+7;
ll sum[maxn],a[maxn],cnt[maxn],num[maxn],t;
int main()
{
    int n,m,x,l,r;
    scanf("%d%d",&n,&m);
    sum[0]=sum[1]=0;
    for(int i=2;i<=n;++i) scanf("%lld",&t),sum[i]=(sum[i-1]+t)%mod;
    for(int i=1;i<=n;++i) scanf("%lld",&a[i]),num[i]=(num[i-1]+a[i]*sum[i]%mod)%mod,cnt[i]=(cnt[i-1]+a[i])%mod;
    while(m--)
    {
        ll t1,t2,t3,t4,t5,t6;
        scanf("%d %d %d",&x,&l,&r);
        if(x<=l)
        {
            t1=(num[r]-num[l-1]+mod)%mod;
            t2=(cnt[r]-cnt[l-1]+mod)%mod;
            t3=t2*sum[x]%mod;
            printf("%lld\n",(t1-t3+mod)%mod);
         }
        else if(x>=r)
        {
            t1=(num[r]-num[l-1]+mod)%mod;
            t2=(cnt[r]-cnt[l-1]+mod)%mod;
            t3=t2*sum[x]%mod;
            printf("%lld\n",(t3-t1+mod)%mod);
        }
        else {
            t1=(cnt[x]-cnt[l-1]+mod)%mod;
            t2=t1*sum[x]%mod;
            t3=(num[x]-num[l-1]+mod)%mod;
            ll ans1=(t2-t3+mod)%mod;
            t1=(num[r]-num[x]+mod)%mod;
            t2=(cnt[r]-cnt[x]+mod)%mod;
            t3=t2*sum[x]%mod;
            ll ans2=(t1-t3+mod)%mod;
            printf("%lld\n",(ans1+ans2)%mod);
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值