HDU 3255 题解 线段树+扫描线
2015-08-18 18:57
489 查看
Farming
Problem DescriptionYou have a big farm, and you want to grow vegetables in it. You’re too lazy to seed the seeds yourself, so you’ve hired n people to do the job for you.
Each person works in a rectangular piece of land, seeding one seed in one unit square. The working areas of different people may overlap, so one unit square can be seeded several times. However, due to limited space, different seeds in one square fight each other – finally, the most powerful seed wins. If there are several “most powerful” seeds, one of them win (it does not matter which one wins).
There are m kinds of seeds. Different seeds grow up into different vegetables and sells for different prices.
As a rule, more powerful seeds always grow up into more expensive vegetables.
Your task is to calculate how much money will you get, by selling all the vegetables in the whole farm.
Input
The first line contains a single integer T (T <= 10), the number of test cases.
Each case begins with two integers n, m (1 <= n <= 30000, 1 <= m <= 3).
The next line contains m distinct positive integers pi (1 <= pi <= 100), the prices of each kind of vegetable.
The vegetables (and their corresponding seeds) are numbered 1 to m in the order they appear in the input.
Each of the following n lines contains five integers x1, y1, x2, y2, s, indicating a working seeded a rectangular area with lower-left corner (x1,y1), upper-right corner (x2,y2), with the s-th kind of seed.
All of x1, y1, x2, y2 will be no larger than 106 in their absolute values.
Output
For each test case, print the case number and your final income.
Sample Input
2
1 1
25
0 0 10 10 1
2 2
5 2
0 0 2 1 1
1 0 3 2 2
Sample Output
Case 1: 2500
Case 2: 16
Source
2009 Asia Regional Ningbo Online
题意
一群人在播种,每个种子占据一个单位(别太在意是什么单位)的正方形块。 但是有时候会有人将几个种子播种在一起,当两个种子在同一个正方形块里面的时候,他们就会相互争夺养分,价格高的植物会活下来。如果他们的价格相同,也得死得只剩一个。 现在给了你m种种子,和播种的正方形坐标,求你可以得到多少钱。
思路
求正方形体积并,高度为相应区间的种子价值,坐标很大需要离散化。考虑到求体积并比较复杂,而一共不超过3种种子,所以转化成求多层面积并。也就是将种子的价值p排序,依次选取>=p[k]的正方形求面积并,然后乘以p[k+1]-p[k]算体积(p[0]=0),即用种子的价值将体积分成多层。线段树用数组模拟,82行代码感觉挺简洁的。
#include <stdio.h> #include <string.h> #include <algorithm> #define MAXN 30002 #define INIT(str) memset(str, 0, sizeof(str)) using namespace std; struct seg { int lx, rx, y, p, flag; bool operator <(const seg& b) const {return y<b.y;} }; seg line[MAXN<<1]; int x[MAXN<<1]; int len[MAXN<<3];//线段累计长度 int sum[MAXN<<3];//多少条线段 void insert(int t, int l, int r, const seg* n) {//由于每个x[i]被标记表示x[i-1]~x[i]被覆盖,所以lx并不用标记,下面的比较符号可能略显纠结 if(x[l]>n->lx && x[r]<=n->rx) sum[t] += n->flag; else { int m = l + r >> 1; if(x[m] > n->lx) insert(t<<1, l, m, n); if(x[m] < n->rx) insert(t<<1|1, m+1, r, n); } if(sum[t]) len[t] = x[r] - x[l-1]; else if(l != r) len[t] = len[t<<1] + len[t<<1|1]; else len[t] = 0; } int main () { int T, t, n, m, y1, y2, type, i, k, sx; scanf("%d", &T); int p[5] = {0}; long long area, ans; for(t=1; t<=T && scanf("%d%d", &n, &m); t++) { for(i=1; i<=m && scanf("%d", p+i); i++); for(i=0, sx=0; i<n; i++, sx+=2) { scanf("%d%d%d%d%d", x+sx, &y1, x+sx+1, &y2, &type); line[i<<1].lx = line[i<<1|1].lx = x[sx]; line[i<<1].rx = line[i<<1|1].rx = x[sx+1]; line[i<<1].p = line[i<<1|1].p = p[type]; line[i<<1].y = y1; line[i<<1|1].y = y2; line[i<<1].flag = 1; line[i<<1|1].flag = -1; } sort(p+1, p+m+1); sort(line, line+n+n); sort(x, x+sx); sx = unique(x, x+sx) - x; for(k=0, ans=0; k<m; k++) { INIT(len); INIT(sum); for(i=0, area=0, y1=0x7fffffff; i<n<<1; i++) if(line[i].p > p[k]) { if(line[i].y > y1) area += (long long)len[1] * (line[i].y - y1); insert(1, 1, sx-1, line+i); y1 = line[i].y; } ans += area * (p[k+1] - p[k]); } printf("Case %d: %I64d\n", t, ans); } return 0; }
相关文章推荐
- hdu 4738 Caocao's Bridges 2013 ACM-ICPC杭州赛区网络赛 1001 双连通分量
- hdu 4750 2013 ACM/ICPC Asia Regional Nanjing Online 1003 并查集+离线操作
- hust 1626 Cutting rope
- 1216: 斐波那契数列
- 1217: 打印沙漏
- 我的ACM-ICPC资源整理
- 2014 ACM-ICPC 亚洲地区赛 西安站小结
- hdu5007 ACM-ICPC 西安赛区网赛A题 水题
- HDU 1394 线段树求逆序数
- Light 1003 - Drunk (拓扑排序)
- TopCoder SRM 659 Div2 Problem 500 - PublicTransit (思维)
- UVa 1529 - Clock (模拟)
- Codeforces 551C - GukiZ hates Boxes (二分 + 贪心)
- TopCoder SRM 660 Div2 Problem 1000 - Powerit (数论)
- UVa 10623 - Thinking Backward (平面图的欧拉公式)
- TopCoder SRM 663 Div2 Problem 500 - ABBA (思维)
- ZOJ 3736 Pocket Cube
- 一位ACMer过来人的心得
- poj1067
- 一位Acmer过来人的经验