首页 > 代码库 > Codeforces 295A. Greg and Array

Codeforces 295A. Greg and Array

题目链接:http://codeforces.com/problemset/problem/295/A

题意:

  给你一个含有 n 个数的数组, 以及 m 个形如 ( l,  r,  v) 的操作,代表把这个数组从第 l 个到第 r 个全部加 v; 然后再给 k 个形如 ( l, r) 的操作,代表对于这 m 个操作, 分别执行第 a 个操作到第 b 个操作各一次.

思路:

  这道题可以分解成两个同样的子问题,设原始数组为 a, 第一个操作为 b, 第二个操作为 c, 可以看到 b 是对于 a 数组从 l 到 r 加 v, 而 c 数组是对 b 的执行次数从 l 到 r 加 1. 这两个问题类似,对 b 设置一个属性 cnt 代表这个命令要执行多少次, 刚开始是不执行的所以初始化为 0 就好,设辅助数组 tp[i] =b[i].cnt - b[i - 1].cnt; 那么对数组 b 从第  l 到第 r 加 1 就相当于 tp[l]++, tp[r + 1]--; 最后再从 1 到 m 对数组 b 执行 b[i].cnt = b[i  - 1].cnt + tp[i]. 这时就可以用 O(N)的复杂度得到对于操作 b, 其每个操作分别执行多少次.然后用同样的方法, 对数组 a 进行操作, 设辅助数组 tp[i] = a[i] - a[ i - 1], 则对与数组 a 从 l 到 r 加 v, 执行 cnt 次, 就相当与执行 tp[l] += cnt * v, tp[r + 1] -= cnt * v, 等所有操作完成后, 再次对于数组 a 进行恢复, 从 1 到 n, 对数组 a 执行 a[i] = a[i  -1] + b[i].那么就可以在 O(n + m) 的时间复杂度里解决该问题.

代码:

 1 #include <bits/stdc++.h> 2  3 using namespace std; 4 typedef long long LL; 5  6 const int MAXN = 100000; 7  8 struct Opera {LL l; LL r; LL v; LL cnt;}; //第一个操作, l r分别为左右区间 v 为所累加的 值, cnt 代表这个操作执行的次数 9 Opera opa[MAXN + 3];10 11 int main() {12     ios_base::sync_with_stdio(0); cin.tie(0);13     int n, m, k; cin >> n >> m >> k;14     LL arv[MAXN + 3] = {0};15     for(int i = 1; i <= n; i++) cin >> arv[i];16     for(int i = 1; i <= m; i++) cin >> opa[i].l >> opa[i].r >> opa[i].v;17     LL bop[MAXN + 3] = {0}; // bop[i] = opa[i].v - opa[i - 1].v, opa[].v 初始化为 0, 所以此数组不用初始化18     for(int i = 0; i < k; i++) {19         int l, r; cin >> l >> r;20         bop[l]++, bop[r + 1]--;// 对数组opa[].v从 l 到 r 加 1, 就相当于 bop[l]++, bop[r + 1]--.21     }22     for(int i = 1; i <= m; i++) opa[i].cnt = opa[i - 1].cnt + bop[i]; //再倒过来恢复, 就可以得到每个操作的次数23     LL ba[MAXN + 3] = {0};  // ba[i] = a[i] - a[i  -1]24     for(int i = 1; i <= n; i++) ba[i] = arv[i] - arv[i - 1];// a[] 每个值不确定, 需要对数组 ba 进行初始化25     for(int i = 1; i <= m; i++) {// 对数组 a 从 opa[i].l 到 opa[i].r 加 v, 且执行 cnt 次的等价变换26         ba[ opa[i].l ] += opa[i].v * opa[i].cnt; 27         ba[ opa[i].r + 1] -= opa[i].v * opa[i].cnt;28     }29     for(int i = 1; i <= n; i++) arv[i] = arv[i - 1] + ba[i]; // 再变化回来30     for(int i = 1; i <= n; i++) cout << arv[i] << (i == n ? \n:  );31     return 0;    32 }

 

Codeforces 295A. Greg and Array