[luoguP3606] [USACO17JAN]Building a Tall Barn建谷仓(贪心 + 线段树)
Posted 蒟蒻zht的博客
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[luoguP3606] [USACO17JAN]Building a Tall Barn建谷仓(贪心 + 线段树)相关的知识,希望对你有一定的参考价值。
把线段都读进来然后排序,先按右端点为第一关键字从小到大排序,后按左端点为第二关键字从小到大排序。
注意不能先按左端点后按右端点排序,否则会出现大包小的情况,如下:
——————
———
—
然后直接线段树搞就行,先求区间最小值,如果大于零就更新统一减1。
——代码
1 #include <cstdio> 2 #include <iostream> 3 #include <algorithm> 4 #define root 1, 1, n 5 #define ls now << 1, l, mid 6 #define rs now << 1 | 1, mid + 1, r 7 8 const int INF = ~(1 << 31), MAXN = 100001; 9 int n, m, ans; 10 int minn[MAXN << 2], add[MAXN << 2]; 11 12 struct node 13 { 14 int a, b; 15 }p[MAXN]; 16 17 inline void swap(int &x, int &y) 18 { 19 x ^= y ^= x ^= y; 20 } 21 22 inline void push_up(int now) 23 { 24 minn[now] = std::min(minn[now << 1], minn[now << 1 | 1]); 25 } 26 27 inline void push_down(int now, int len) 28 { 29 if(!add[now]) return; 30 add[now << 1] += add[now]; 31 add[now << 1 | 1] += add[now]; 32 minn[now << 1] += add[now]; 33 minn[now << 1 | 1] += add[now]; 34 add[now] = 0; 35 } 36 37 inline void build(int now, int l, int r) 38 { 39 if(l == r) 40 { 41 scanf("%d", &minn[now]); 42 return; 43 } 44 int mid = (l + r) >> 1; 45 build(ls); 46 build(rs); 47 push_up(now); 48 } 49 50 inline bool cmp(node x, node y) 51 { 52 return x.b == y.b ? x.a < y.a : x.b < y.b; 53 } 54 55 inline int query(int x, int y, int now, int l, int r) 56 { 57 if(x <= l && r <= y) return minn[now]; 58 if(l > y || r < x) return INF; 59 push_down(now, r - l + 1); 60 int mid = (l + r) >> 1; 61 return std::min(query(x, y, ls), query(x, y, rs)); 62 } 63 64 inline void update(int x, int y, int now, int l, int r) 65 { 66 if(x <= l && r <= y) 67 { 68 minn[now]--; 69 add[now]--; 70 return; 71 } 72 if(l > y || r < x) return; 73 push_down(now, r - l + 1); 74 int mid = (l + r) >> 1; 75 update(x, y, ls); 76 update(x, y, rs); 77 push_up(now); 78 } 79 80 int main() 81 { 82 int i, j; 83 scanf("%d %d", &n, &m); 84 build(root); 85 for(i = 1; i <= m; i++) 86 { 87 scanf("%d %d", &p[i].a, &p[i].b); 88 if(p[i].a > p[i].b) swap(p[i].a, p[i].b); 89 } 90 std::sort(p + 1, p + m + 1, cmp); 91 for(i = 1; i <= m; i++) 92 if(query(p[i].a, p[i].b, root) > 0) 93 ans++, update(p[i].a, p[i].b, root); 94 printf("%d", ans); 95 return 0; 96 }
以上是关于[luoguP3606] [USACO17JAN]Building a Tall Barn建谷仓(贪心 + 线段树)的主要内容,如果未能解决你的问题,请参考以下文章
LuoguP2876 [USACO07JAN]解决问题Problem Solving (区间DP)(未完成)
[luogu P2205] [USACO13JAN]画栅栏Painting the Fence
[LuoguP3668][USACO17OPEN]现代艺术2
[BZOJ 3048][Luogu P3069][USACO2013 Jan]Cow Lineup