CF 179(div2) C(线段树 || 扫描法 )
2013-05-12 09:16
603 查看
C. Greg and Array
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
Greg has an array a = a1, a2, ..., an and
m operations. Each operation looks as:
li,
ri,
di,
(1 ≤ li ≤ ri ≤ n). To apply operation
i to the array means to increase all array elements with numbers
li, li + 1, ..., ri by value
di.
Greg wrote down k queries on a piece of paper. Each query has the following form:
xi,
yi,
(1 ≤ xi ≤ yi ≤ m). That means that one should apply operations with numbers
xi, xi + 1, ..., yi to the array.
Now Greg is wondering, what the array a will be after all the queries are executed. Help Greg.
Input
The first line contains integers n,
m, k
(1 ≤ n, m, k ≤ 105). The second line contains
n integers: a1, a2, ..., an
(0 ≤ ai ≤ 105) — the initial array.
Next m lines contain operations, the operation number
i is written as three integers:
li,
ri,
di,
(1 ≤ li ≤ ri ≤ n),
(0 ≤ di ≤ 105).
Next k lines contain the queries, the query number
i is written as two integers:
xi,
yi,
(1 ≤ xi ≤ yi ≤ m).
The numbers in the lines are separated by single spaces.
Output
On a single line print n integers
a1, a2, ..., an — the array after executing all the queries. Separate the printed numbers by spaces.
Please, do not use the %lld specifier to read or write 64-bit integers in
C++. It is preferred to use the
cin, cout streams of the
%I64d specifier.
Sample test(s)
Input
Output
Input
Output
Input
Output
这道题有两种做法,第一种也是最常想到的维护两颗线段树。其实这道题有另一种O(n)的算法,因为我们最后只查询一次,所以是不需要线段树的。关键是找到类似线段树lazy的另一种数据结构。用一个count数组记录,a是累加后的结果,关键代码就是这句了
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
Greg has an array a = a1, a2, ..., an and
m operations. Each operation looks as:
li,
ri,
di,
(1 ≤ li ≤ ri ≤ n). To apply operation
i to the array means to increase all array elements with numbers
li, li + 1, ..., ri by value
di.
Greg wrote down k queries on a piece of paper. Each query has the following form:
xi,
yi,
(1 ≤ xi ≤ yi ≤ m). That means that one should apply operations with numbers
xi, xi + 1, ..., yi to the array.
Now Greg is wondering, what the array a will be after all the queries are executed. Help Greg.
Input
The first line contains integers n,
m, k
(1 ≤ n, m, k ≤ 105). The second line contains
n integers: a1, a2, ..., an
(0 ≤ ai ≤ 105) — the initial array.
Next m lines contain operations, the operation number
i is written as three integers:
li,
ri,
di,
(1 ≤ li ≤ ri ≤ n),
(0 ≤ di ≤ 105).
Next k lines contain the queries, the query number
i is written as two integers:
xi,
yi,
(1 ≤ xi ≤ yi ≤ m).
The numbers in the lines are separated by single spaces.
Output
On a single line print n integers
a1, a2, ..., an — the array after executing all the queries. Separate the printed numbers by spaces.
Please, do not use the %lld specifier to read or write 64-bit integers in
C++. It is preferred to use the
cin, cout streams of the
%I64d specifier.
Sample test(s)
Input
3 3 3 1 2 3 1 2 1 1 3 2 2 3 4 1 2 1 3 2 3
Output
9 18 17
Input
1 1 1 1 1 1 1 1 1
Output
2
Input
4 3 6
1 2 3 4
1 2 1
2 3 23 4 4
1 21 3
2 3
1 21 3
2 3
Output
这道题有两种做法,第一种也是最常想到的维护两颗线段树。其实这道题有另一种O(n)的算法,因为我们最后只查询一次,所以是不需要线段树的。关键是找到类似线段树lazy的另一种数据结构。用一个count数组记录,a是累加后的结果,关键代码就是这句了
for(int i = 1;i <= m;i++){ countn[l[i]-1] += d[i];countn[r[i]] -= d[i]; } sum = 0; for(int i = 0;i <= n;i++){ a[i] += sum;sum += countn[i]; }读者自己动手模拟一遍就能看出里面的思路了
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define LL long long using namespace std; const int maxn = 100100; LL a[maxn],l[maxn],r[maxn],d[maxn]; LL countn[maxn],ll[maxn],rr[maxn]; int main(){ int n,m,k; while(scanf("%d%d%d",&n,&m,&k) != EOF){ for(int i = 1;i <= n;i++) cin >> a[i]; for(int i = 1;i <= m;i++) cin >> l[i] >> r[i] >> d[i]; memset(countn,0,sizeof(countn)); for(int i = 0;i < k;i++){ int teml,temr; cin >> teml >> temr; countn[teml-1] += 1;countn[temr] -= 1; } LL sum = 0; for(int i = 0;i <= m;i++){ d[i] *= sum; sum += countn[i]; } memset(countn,0,sizeof(countn)); for(int i = 1;i <= m;i++){ countn[l[i]-1] += d[i];countn[r[i]] -= d[i]; } sum = 0; for(int i = 0;i <= n;i++){ a[i] += sum;sum += countn[i]; } for(int i = 1;i < n;i++) cout << a[i] << ' '; cout << a << endl; } return 0; }
相关文章推荐
- CF 275 div2 D. Interesting Array (线段树)
- CF 179(div2)D(floyed)
- CF 296 div2 C. Glass Carving (线段树)
- CF 242E(div 2) n课线段树更新
- Codeforces Round #179 (Div. 1) A题 线段树
- Codeforces Round #271 (Div. 2)(dp,线段树good)(很好的一场cf)
- cf/Codeforces Round #373 div1-C/div2-E Sasha and Array 线段树 + 维护矩阵快速幂
- [CF#365 (Div. 2) Mishka and Interesting sum] 线段树离线处理区间不同数
- 【CF720D】Slalom 扫描线+线段树
- CF-Div2-207-C题+线段树
- 严格上升子序列 dp CF Round_FF div1 A
- cf 267 div2 E Alex and Complicated Task
- CF# Wunder Fund Round 2016 (Div. 1 + Div. 2 combined) C计算几何 + D 图论
- CF 629D Babaei and Birthday Cake(线段树单点更新)
- CF(#293 div2):A:Vitaly and Strings
- BZOJ2951: [Poi2001]Goldmine 扫描线+线段树
- Codeforces Round #254 (Div. 1) C. DZY Loves Colors 线段树
- Codeforces Round #376 (Div. 2) D 线段树区间维护
- CF div2 332 C
- POJ 1151 Atlantis( 线段树 + 扫描线 )