【每日一题】30.储物点的距离 (区间处理,前缀和/线段树//树状数组)

补题链接:Here

算法涉及:前缀和,思维

一个数轴,每一个储物点会有一些东西,同时它们之间存在距离。

每次给个区间 [l,r] ,查询把这个区间内所有储物点的东西运到另外一个储物点的代价是多少?

比如储物 i 点有x 个东西,要运到储物点 j ,代价为 xdit(i,j)

dist(i, j) = abs(i - j) 就是储物点间的距离。

【解题思路】

对于一个区间 [l,r] , 总的代价为 i=lrb[i]abs(a[i]a[x])
对于最终点 x , 我们可以分三种情况:

  • rx,那么上面式子里的绝对值去掉得到 i=lrb[i]abs(a[i]a[x])=a[x]i=lrb[i]i=lra[i]b[i]

  • xl,那么上面式子里的绝对值去掉得到i=lrb[i]abs(a[i]a[x])=a[x]i=lrb[i]+i=lra[i]b[i]

  • l<x<r , 那么对区间 [l,x1],[x,r] 分别做上述的操作即可

观察发现可以维护两个前缀和, i=lra[i]b[i]i=lrb[i] , 那么上述每次查询操作就能够 O(1)

  • 最后万分提醒,取模、取模再取模。。。Debug 超久
using ll = long long;
const int mod = 1e9 + 7;
const int N = 2e5 + 10;
ll a[N], b[N], c[N], sum[N];
void solve() {
    int n, m;
    cin >> n >> m;
    for (int i = 2; i <= n; ++i) {
        cin >> a[i]; // n - 1个数,第i个数表示第i个储物点与第i+1个储物点的距离ai
        a[i] = (a[i - 1] + a[i]) %  mod;
    }
    for (int i = 1; i <= n; ++i) {
        cin >> b[i]; // 每个储物点的东西个数bi
        c[i] = (a[i] * b[i]) % mod;
        b[i] = (b[i] + b[i - 1]) % mod;
        sum[i] = (sum[i - 1] + c[i]) % mod;
    }
    int l, r, x;
    while (m--) {
        cin >> x >> l >> r;
        ll ans = 0;
        if (x >= r) { // 情况 1
            ans = a[x] * ((b[r] - b[l - 1] + mod) % mod) % mod;
            ans = (ans - ((sum[r] - sum[l - 1] + mod) % mod) + mod) % mod;
            ans = (ans + mod) % mod;
            cout << ans << "\n";
        } else if (l >= x) { // 情况 2
            ans = (sum[r] - sum[l - 1] + mod) % mod;
            ans = (ans - a[x] * ((b[r] - b[l - 1] + mod) % mod) + mod)  % mod;
            ans = (ans + mod) % mod;
            cout << ans << "\n";
        } else { // 情况 3
            ll ans1 = (sum[r] - sum[x - 1] + mod) % mod;
            ans1 = (ans1 - (a[x] * ((b[r] - b[x - 1]) + mod % mod)) + mod) % mod;
            ans1 = (ans1 + mod) % mod;
            ll ans2 = (a[x] * ((b[x - 1] - b[l - 1] + mod) % mod)) % mod;
            ans2 = (ans2 - ((sum[x - 1] - sum[l - 1] + mod) % mod) + mod) % mod;
            ans2 = (ans2 + mod) % mod;
            cout << (ans1 + ans2) % mod << "\n";
        }
    }
}
posted @   RioTian  阅读(111)  评论(0编辑  收藏  举报
编辑推荐:
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· Obsidian + DeepSeek:免费 AI 助力你的知识管理,让你的笔记飞起来!
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 全程不用写代码,我用AI程序员写了一个飞机大战
历史上的今天:
2020-05-20 POJ:1511 Invitation Cards(双向搜索最短路径)
2020-05-20 ACM:快读读入技巧
点击右上角即可分享
微信分享提示