HDU 3255 题解 线段树+扫描线
来源:互联网 发布:桃源恋歌动作数据 编辑:程序博客网 时间:2024/06/07 20:56
Farming
Problem Description
You 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 3255 题解 线段树+扫描线
- HDU 3255 Farming(线段树:扫描线)
- 【HDU5770】【线段树】【扫描线】Treasure 题解
- hdu 3255 Farming (线段树扫描线球体积并)
- hdu 1542 线段树扫描线
- hdu 3265 Posters 线段树+扫描线
- hdu 1828 线段树+扫描线
- hdu 3265 线段树+扫描线
- hdu 4007 扫描线 线段树
- HDU 3265 线段树 扫描线
- hdu 1542 Atlantis 线段树扫描线
- HDU 1542 Atlantis(线段树:扫描线)
- HDU 1828 Picture(线段树:扫描线)
- HDU 3265 Posters(线段树:扫描线)
- 【HDU】1542 Atlantis 线段树+扫描线
- HDU 1542 Atlantis(线段树扫描线)
- HDU - 1542 (扫描线+线段树优化)
- hdu 1264 线段树+扫描线
- category和protocol 第五天稍晚了一些。
- 关于double类型数字相加位数发生变化的问题
- Travelling Salesman Problem (hdu 5402 模拟)
- Android开源项目汇总
- hdu5396 Expression 区间dp +排列组合
- HDU 3255 题解 线段树+扫描线
- Linux基础篇
- iOS OC Label 详解
- gpgpu review
- 我第一个Python教程笔记
- 【多校第9场】【组合数学】【区间dp】【Expression】
- R语言基础绘图包--控制axis label位置--par(mgp)与mtext
- 【套汇】【bell-ford变形】
- 【vijos P1010】清帝之惑之乾隆 c++题解