【每日一题】5月15日储物点的距离
储物点的距离
https://ac.nowcoder.com/acm/problem/14683
解题思路
前缀和,千万千万注意减法取模……我半个多小时。。
区间问题,居然要全部转移那么最简单模拟的话,出题人变态一点,每个区间都是最左端和最右端。时间复杂度毫无疑问爆炸了
这时候,昨天的直播课,雨巨小姐姐刚好又说到了区间问题的解决办法!!吹爆。每个步骤都去模拟太蠢了,想想能不能用前缀和代替一下。
区间问题解决办法一般有前缀和,树状数组,线段树,码量也是依次增大,当然能力也是依次增大。
放到这个题目上,给出每个相邻点距离,我们选取1作为源点,一次前缀和,可以得到每个点到1的距离。
第二个是物品数量,那么一次前缀和就可以得到区间内有多少物品。
第三个,这个也是比较不好想的也是本题解题的关键。新开一个数组,存放每个位置全部物品转移到源点的花费前缀和。
那么每次对于区间的查询,如果x在l之前,那么把区间物品移动到源点,多走的距离就是x到源点距离,拿区间物品数目乘以距离再减掉就行了。
对于x在r之后,那就是把这些物品从x移动到源点,多走的部分就是,这些物品移动到源点的花费,减掉即可。
对于在l,r之间的,分成前后两段分别按照前面两种方法求解即可。
千万千万千万注意减法的MOD运算吖,我哭了。
#include <bits/stdc++.h> #pragma GCC optimize(2) #pragma GCC optimize(3) using namespace std; #define js ios::sync_with_stdio(false);cin.tie(0); cout.tie(0) typedef long long ll; inline ll read() { ll s = 0, w = 1; char ch = getchar(); while (ch < 48 || ch > 57) { if (ch == '-') w = -1; ch = getchar(); } while (ch >= 48 && ch <= 57) s = (s << 1) + (s << 3) + (ch ^ 48), ch = getchar(); return s * w; } inline void write(ll x) { if (!x) { putchar('0'); return; } char F[200]; ll tmp = x > 0 ? x : -x; if (x < 0)putchar('-'); int cnt = 0; while (tmp > 0) { F[cnt++] = tmp % 10 + '0'; tmp /= 10; } while (cnt > 0)putchar(F[--cnt]); } const int N = 2e5 + 7; const int MOD = 1e9 + 7; ll a[N], b[N], c[N]; int main() { int n = read(), m = read(); for (int i = 2; i <= n; ++i) a[i] = read(), a[i] = (a[i] + a[i - 1]) % MOD; for (int i = 1; i <= n; ++i) { b[i] = read(); c[i] = (c[i - 1] + a[i] * b[i]) % MOD; b[i] = (b[i - 1] + b[i]) % MOD; } while (m--) { int x = read(), l = read(), r = read(); ll ans = 0; if (x <= l) { ans = (c[r] - c[l - 1] + MOD) % MOD; ans = (ans - (b[r] - b[l - 1] + MOD) % MOD * a[x] % MOD + MOD) % MOD; } else if (x >= r) { ans = (b[r] - b[l - 1] + MOD) % MOD * a[x] % MOD; ans = (ans - (c[r] - c[l - 1] + MOD) % MOD + MOD) % MOD; } else { ans = (c[r] - c[x] + MOD) % MOD; ans = (ans - (b[r] - b[x] + MOD) % MOD * a[x] % MOD + MOD) % MOD; ans = (ans + (b[x] - b[l - 1] + MOD) % MOD * a[x] % MOD - (c[x] - c[l - 1] + MOD) % MOD + MOD) % MOD; } write(ans), putchar('\n'); } return 0; }
每日一题 文章被收录于专栏
每日一题