Codeforces 295A. Greg and Array

Posted Ashly

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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的主要内容,如果未能解决你的问题,请参考以下文章

295B - Greg and Graph (floyd逆序处理)

G - Greg and Array CodeForces - 296C 差分+线段树

codeforces 521a//DNA Alignment// Codeforces Round #295(Div. 1)

Codeforces-295记录

Greg and graph

[Codeforces]#179 div1-----295ABCDE