博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Codeforces 295A Greg and Array
阅读量:5217 次
发布时间:2019-06-14

本文共 5558 字,大约阅读时间需要 18 分钟。

A. Greg and Array
time limit per test   1.5 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 2 3 4 4 1 2 1 3 2 3 1 2 1 3 2 3
Output
5 18 31 20 分析 线段树。 离线预处理所有Query,统计各operation的次数。 区间Insert,注意使用lazy-tag,点Query答案。 写法 要维护两棵线段树,可并做一棵。 这是我第一次写的,TLE on test 24
1 #include
2 using namespace std; 3 const int MAX_N=1e5+10; 4 typedef long long ll; 5 6 struct op{ 7 int l, r; 8 ll v; 9 }o[MAX_N];10 11 ll cnt[MAX_N], a[MAX_N];12 13 struct Node{14 int l, r;15 ll v;16 int mid(){
return (l+r)>>1;}17 }T[MAX_N<<2];18 19 void Build(int id, int l, int r){20 T[id].l=l, T[id].r=r, T[id].v=0;21 if(l==r) return;22 int mid=T[id].mid();23 Build(id<<1, l, mid);24 Build(id<<1|1, mid+1, r);25 }26 void Insert(int id, int l, int r, ll v){27 Node &now=T[id];28 if(now.l>=l&&now.r<=r){29 if(~now.v) now.v+=v;30 else{31 Insert(id<<1, l, r, v);32 Insert(id<<1|1, l, r, v);33 }34 }35 else{36 Node &lch=T[id<<1], &rch=T[id<<1|1];37 if(~now.v) lch.v=rch.v=now.v, now.v=-1; //ERROR-PRONE38 int mid=now.mid();39 if(l<=mid) Insert(id<<1, l, r, v);40 if(r>mid) Insert(id<<1|1, l, r, v);41 if(lch.v==rch.v) now.v=lch.v;42 }43 }44 45 void Qurery(int id, ll *a){46 Node &now=T[id];47 if(~now.v)48 for(int i=now.l; i<=now.r; i++) a[i]+=now.v;49 else{50 Qurery(id<<1, a);51 Qurery(id<<1|1, a);52 }53 }54 55 int main(){56 //freopen("in", "r", stdin);57 int N, M, K;58 scanf("%d%d%d", &N, &M, &K);59 for(int i=1; i<=N; i++) scanf("%lld", a+i);60 for(int i=1; i<=M; i++)61 scanf("%d%d%lld", &o[i].l, &o[i].r, &o[i].v);62 Build(1, 1, M);63 int l, r;64 while(K--){65 scanf("%d%d", &l, &r);66 Insert(1, l, r, 1);67 }68 Qurery(1, cnt);69 Build(1, 1, N);70 for(int i=1; i<=M; i++)71 if(cnt[i])72 Insert(1, o[i].l, o[i].r, o[i].v*cnt[i]);73 Qurery(1, a);74 for(int i=1; i<=N; i++)75 printf("%lld ", a[i]);76 puts("");77 return 0;78 }

 

上面的代码没有lazy-tag或者说我设置的lazy-tag没起到相应的作用。我的考虑是设置一个tag,最后求答案时可不必细分到每个叶子节点,但是这种优化对降低Insert的复杂度没有太大帮助,而Insert是最耗时的,因而总的复杂度还是没降下来。 AC的姿势
1 #include
2 using namespace std; 3 const int MAX_N=1e5+10; 4 typedef long long ll; 5 6 struct op{ 7 int l, r, v; 8 }o[MAX_N]; 9 10 ll cnt[MAX_N], a[MAX_N];11 12 struct Node{13 int l, r;14 ll v;15 int mid(){
return (l+r)>>1;}16 }T[MAX_N<<2];17 18 void Build(int id, int l, int r){19 T[id].l=l, T[id].r=r, T[id].v=0;20 if(l==r) return;21 int mid=T[id].mid();22 Build(id<<1, l, mid);23 Build(id<<1|1, mid+1, r);24 }25 void Insert(int id, int l, int r, ll v){26 Node &now=T[id];27 if(now.l>=l&&now.r<=r) now.v+=v;28 else{29 Node &lch=T[id<<1], &rch=T[id<<1|1];30 if(now.v) 31 lch.v+=now.v, rch.v+=now.v, now.v=0;32 int mid=now.mid();33 if(l<=mid) Insert(id<<1, l, r, v);34 if(r>mid) Insert(id<<1|1, l, r, v);35 }36 }37 38 void Qurery(int id, ll *a){39 Node &now=T[id];40 if(now.l==now.r) a[now.l]+=now.v;41 else{42 Node &lch=T[id<<1], &rch=T[id<<1|1];43 if(now.v) 44 lch.v+=now.v, rch.v+=now.v;45 Qurery(id<<1, a);46 Qurery(id<<1|1, a);47 }48 }49 50 int main(){51 //freopen("in", "r", stdin);52 int N, M, K;53 scanf("%d%d%d", &N, &M, &K);54 for(int i=1; i<=N; i++) scanf("%lld", a+i);55 for(int i=1; i<=M; i++)56 scanf("%d%d%lld", &o[i].l, &o[i].r, &o[i].v);57 Build(1, 1, M);58 int l, r;59 while(K--){60 scanf("%d%d", &l, &r);61 Insert(1, l, r, 1);62 }63 Qurery(1, cnt);64 Build(1, 1, N);65 for(int i=1; i<=M; i++)66 if(cnt[i]&&o[i].v)67 Insert(1, o[i].l, o[i].r, o[i].v*cnt[i]);68 Qurery(1, a);69 for(int i=1; i<=N; i++)70 printf("%lld ", a[i]);71 puts("");72 return 0;73 }

 

 

 

 

 

转载于:https://www.cnblogs.com/Patt/p/4679936.html

你可能感兴趣的文章
你的日志组件记录够清晰嘛?--自己开发日志组件 Logger
查看>>
简版的文件传输
查看>>
input(Text)控件作为填空输入,但运行后,有曾经输入的记录显示,用autocomplete="off"解决...
查看>>
Java多线程
查看>>
长春理工大学第十四届程序设计竞赛(重现赛)J
查看>>
统计一篇英文文章内每个单词出现频率,并返回出现频率最高的前10个单词及其出现次数...
查看>>
leetcode36 有效数独
查看>>
jQuery选择器和遍历的总结
查看>>
ThreadPerMessagePattern——关于匿名内部类
查看>>
osg 3ds模型加载与操作
查看>>
[转帖]IBM收购红帽价格是多少?是否会形成垄断企业?会存在什么不安因素?...
查看>>
[转]Whirlwind Tour of ARM Assembly
查看>>
python socket.error: [Errno 10054] 解决方法
查看>>
JavaScript 高级篇之函数 (五)
查看>>
本周个人总结
查看>>
C# 中在Form控件创建以外的线程操作控件问题
查看>>
改写二分搜索算法及对于问题的理解
查看>>
Java-分治算法
查看>>
Linux xinetd使用指南
查看>>
@NOIP2018 - D2T1@ 旅行
查看>>