51nod1287(二分/线段树区间最值&单点更新)
Posted ygeloutingyu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了51nod1287(二分/线段树区间最值&单点更新)相关的知识,希望对你有一定的参考价值。
题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1287
题意:中文题诶~
解法1:b[i] 存储 max(a[0], ....., a[i]),显然 b 是单调不减的,所以直接二分 x,再更新 a 和 b 数组即可;
代码:
1 #include <iostream> 2 #include <stdio.h> 3 using namespace std; 4 5 const int MAXN = 5e4 + 10; 6 int a[MAXN], b[MAXN], x; 7 8 int main(void){ 9 int n, m; 10 scanf("%d%d", &n, &m); 11 for(int i = 0; i < n; i++){ 12 scanf("%d", &a[i]); 13 if(i == 0) b[i] = a[i]; 14 else b[i] = max(b[i - 1], a[i]); 15 } 16 while(m--){ 17 scanf("%d", &x); 18 if(x <= a[0] || x > b[n - 1]) continue; 19 int pos = lower_bound(b, b + n, x) - b; 20 a[pos - 1]++; 21 b[pos - 1] = max(b[pos - 1], a[pos - 1]); 22 } 23 for(int i = 0; i < n; i++){ 24 printf("%d\n", a[i]); 25 } 26 return 0; 27 }
解法2:用线段树维护区间最大值,再更新一下 a 数组即可;
代码:
1 #include <iostream> 2 #include <stdio.h> 3 #define lson l, mid, rt << 1 4 #define rson mid + 1, r, rt << 1 | 1 5 using namespace std; 6 7 const int MAXN = 5e4 + 10; 8 int Max[MAXN << 2]; 9 int a[MAXN]; 10 11 void push_up(int rt){ 12 Max[rt] = max(Max[rt << 1], Max[rt << 1 | 1]); 13 } 14 15 void build(int l, int r, int rt){ 16 if(l == r){ 17 Max[rt] = a[l]; 18 return; 19 } 20 int mid = (l + r) >> 1; 21 build(lson); 22 build(rson); 23 push_up(rt); 24 } 25 26 void update(int p, int x, int l, int r, int rt){ 27 if(l == r){ 28 Max[rt] += x; 29 return; 30 } 31 int mid = (l + r) >> 1; 32 p <= mid ? update(p, x, lson) : update(p, x, rson); 33 push_up(rt); 34 } 35 36 37 int query(int x, int l, int r, int rt){ 38 if(l == r) return l; 39 int mid = (l + r) >> 1; 40 return Max[rt << 1] >= x ? query(x, lson) : query(x, rson); 41 } 42 43 44 int main(void){ 45 int n, m, x; 46 scanf("%d%d", &n, &m); 47 for(int i = 1; i <= n; i++){ 48 scanf("%d", &a[i]); 49 } 50 build(1, n , 1); 51 while(m--){ 52 scanf("%d", &x); 53 if(x > Max[1] || x <= a[1]) continue; 54 int index = query(x, 1, n, 1); 55 a[index - 1] += 1; 56 update(index - 1, 1, 1, n, 1); 57 } 58 for(int i = 1; i <= n; i++){ 59 printf("%d\n", a[i]); 60 } 61 return 0; 62 }
以上是关于51nod1287(二分/线段树区间最值&单点更新)的主要内容,如果未能解决你的问题,请参考以下文章