[51nod 1208] Stars in Your Window(线段树,扫描线)

题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1208

题意:也是矩形框点问题,不过每个点有权值,希望权值最大。

直接把出入的event中的sign变成对应权值,更新到线段树上就行了。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3
 4 #define lrt rt << 1
 5 #define rrt rt << 1 | 1
 6 typedef struct Seg {
 7     int add, val;
 8 }Seg;
 9 typedef struct Event {
10     int l, r, h, val;
11 }Event;
12 const int maxn = 100500;
13 Seg seg[maxn<<4];
14 vector<Event> event;
15 int hh[maxn<<1], hcnt;
16 int n, w, h;
17
18 bool cmp(Event a, Event b) {
19     if(a.h != b.h) return a.h < b.h;
20     return a.val > b.val;
21 }
22
23 void build(int l, int r, int rt) {
24     seg[rt].val = seg[rt].add = 0;
25     if(l == r) return;
26     int mid = (l + r) >> 1;
27     build(l, mid, lrt);
28     build(mid+1, r, rrt);
29 }
30
31
32 void pushup(int rt) {
33     seg[rt].val = max(seg[lrt].val, seg[rrt].val);
34 }
35
36 void pushdown(int rt) {
37     if(seg[rt].add) {
38         seg[lrt].add += seg[rt].add;
39         seg[rrt].add += seg[rt].add;
40         seg[lrt].val += seg[rt].add;
41         seg[rrt].val += seg[rt].add;
42         seg[rt].add = 0;
43     }
44 }
45
46 void update(int L, int R, int val, int l, int r, int rt) {
47     if(L <= l && r <= R) {
48         seg[rt].add += val;
49         seg[rt].val += val;
50         return;
51     }
52     pushdown(rt);
53     int mid = (l + r) >> 1;
54     if(L <= mid) update(L, R, val, l, mid, lrt);
55     if(mid < R) update(L, R, val, mid+1, r, rrt);
56     pushup(rt);
57 }
58
59 int id(int x) {
60     return lower_bound(hh, hh+hcnt, x) - hh + 1;
61 }
62
63 int main() {
64     // freopen("in", "r", stdin);
65     int x, y, v;
66     while(~scanf("%d%d%d",&n,&w,&h)) {
67         event.clear(); hcnt = 0;
68         for(int i = 0; i < n; i++) {
69             scanf("%d%d%d",&x,&y,&v);
70             event.push_back(Event{x, x+w, y, v});
71             event.push_back(Event{x, x+w, y+h, -v});
72             hh[hcnt++] = x; hh[hcnt++] = x + w;
73         }
74         sort(event.begin(), event.end(), cmp);
75         sort(hh, hh+hcnt); hcnt = unique(hh, hh+hcnt) - hh;
76         build(1, hcnt, 1);
77         int ret = 0;
78         for(int i = 0; i < event.size(); i++) {
79             int l = id(event[i].l);
80             int r = id(event[i].r);
81             int val = event[i].val;
82             update(l, r, val, 1, hcnt, 1);
83             ret = max(ret, seg[1].val);
84         }
85         printf("%d\n", ret);
86     }
87     return 0;
88 }
时间: 2024-11-10 13:06:07

[51nod 1208] Stars in Your Window(线段树,扫描线)的相关文章

POJ 2482 Stars in Your Window 线段树扫描线

Stars in Your Window Description Fleeting time does not blur my memory of you. Can it really be 4 years since I first saw you? I still remember, vividly, on the beautiful Zhuhai Campus, 4 years ago, from the moment I saw you smile, as you were walkin

POJ 2482 Stars in Your Window 线段树+离散化+扫描线

题面据说很美- 每个星星可以根据在窗口的左下角和右上角两个位置建立两条扫描线,之后就是简单的区间增减和求最大值操作了. 注意要处理在边界上的星星是不算的情况,其实只要把左右边界分别增减一个eps即可. #include <cstdio> #include <cstring> #include <iostream> #include <map> #include <set> #include <vector> #include <

POJ 2482 stars in your window(线段树 , 扫描线)

题目大意: 给你10000以内的星星的坐标和亮度,让你用一个W × H 的矩形去围住一个区域,使得区域内星星的亮度最大,矩形边缘上的星星不算. 解题思路: 对于每一个星星 建立一个(x, y , y + h , c) 的扫描线 和一个(x + w , y , y + h , - c)的扫描线,将问题转化成求区间最大值.几个需要注意的地方:矩形边缘上的需要处理一下,将每个叶节点设为长度为1的线段.另外此题如果用long long wa掉的话可以改为unsigned. #include <iostr

【BZOJ】1382: [Baltic2001]Mars Maps (线段树+扫描线)

1382: [Baltic2001]Mars Maps Time Limit: 5 Sec  Memory Limit: 64 MB Description 给出N个矩形,N<=10000.其坐标不超过10^9.求其面积并 Input 先给出一个数字N,代表有N个矩形. 接下来N行,每行四个数,代表矩形的坐标. Output 输出面积并 Sample Input 2 10 10 20 20 15 15 25 30 Sample Output 225 本以为是傻逼题,没想到不容易啊- 线段树+扫描

BZOJ 4059 Cerc2012 Non-boring sequences 线段树+扫描线

题目大意:定义一个序列为[不无聊的]当且仅当这个序列的任意一个区间都存在一个数只出现过一次,给定一个序列,要求判断这个序列是否是[不无聊的] 定义lasti表示第i个元素上一次出现的位置(第一次出现则为0),nexti表示第i个元素下一次出现的位置(最后一次出现则为n+1),那么这个元素能成为某个区间仅出现一次的数,当且仅当这个区间的左端点在[lasti+1,i]之间,右端点在[i,nexti?1]之间 我们可以将区间的左右端点放在二维平面上,那么一个元素产生的贡献是一个矩形,我们要确定的是所有

HDU 4419 Colourful Rectangle --离散化+线段树扫描线

题意: 有三种颜色的矩形n个,不同颜色的矩形重叠会生成不同的颜色,总共有R,G,B,RG,RB,GB,RGB 7种颜色,问7种颜色每种颜色的面积. 解法: 很容易想到线段树扫描线求矩形面积并,但是如何维护每种颜色的长度着实让我伤透了脑筋.后来看了一位朋友的题解,才幡然醒悟. 开始想到了用二进制表示颜色,R用001表示,G用010表示,B用100表示.那么就可以用十进制1~7表示7种不同颜色了. 维护 cov[rt][1~3] 表示此区间内3种原色各有多少个, Len[rt][i]表示每种颜色的长

sgu316Kalevich Strikes Back(线段树+扫描线)

做法:总体想法是求出一个矩形的面积以及它所包含的矩形,然后用自己的面积减掉所包含的.主要问题是怎样求解它所包含的矩形. 因为是没有相交点的,可以利用扫描线的方法去做,类似染色,当前段如果是x色,也就是第x个矩形,那么再把他染成y颜色时,说明x包含y,而当扫到y的上边时,这一段又恢复到x色.标记一下被包含的矩形,记录所包含的矩形. 因为会有恢复染色操作,up需要时时更新,左儿子和右儿子一样颜色时就可以合并为一段. 1 ; 2 } 3 void down(int w) 4 { 5 if(s[w]!=

hdu1255 覆盖的面积 线段树-扫描线

矩形面积并 线段树-扫描线裸题 1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 #include<math.h> 5 using namespace std; 6 const int maxm=2e3+5; 7 const double eps=1e-5; 8 9 struct seg{ 10 double x,y1,y2; 11 int c; 12 bool operator

线段树+扫描线 HDOJ 5091 Beam Cannon

题目传送门 1 /* 2 题意:给出若干个点的坐标,用一个矩形去覆盖,问最多能覆盖几个点 3 线段树+扫描线:思路是先建一棵以[y, y + h]的树,左右儿子[x, x + w] 4 以这棵树为范围,从左到右扫描,更新点数,x的+1, x+w的-1(超过矩形范围) 5 ans = 每次更新时所覆盖点数的最大值 6 */ 7 #include <cstdio> 8 #include <algorithm> 9 #include <iostream> 10 #includ