HDU 1156 Brownie Points II
来源:互联网 发布:彩弹枪淘宝有么 编辑:程序博客网 时间:2024/05/18 00:14
题目地址
题意:给你n个点,然后你选择在坐标系选择一条垂直于x轴并经过一个点的线,然后再通过那个点做一条垂直于y轴的线,这样就形成了一个新的坐标系,第一象限和第三象限的点数为st的分数,第二象限和第四象限的点数为ol的分数,求出st最坏的情况下的最高分,并求出当时ol的分数
思路:个人对这题的理解还不是很透彻,希望有人能给我指出来,因为我们的点是按x坐标大小排序的,然后在相同x坐标,所以st画的线是一样的,所以只有ol不一样,但是我们在线段树上存的是高于该点y坐标有多少个点以及低于该点y坐标有多少个点,所以这样就把象限划分出来了。(这是我现在的理解,稍后理解清楚了一点会更新)
PS:我感觉这题还是树状数组写的比较好理解。
线段树写法:
#include <iostream>#include <cstring>#include <string>#include <queue>#include <vector>#include <map>#include <set>#include <stack>#include <cmath>#include <cstdio>#include <algorithm>#define N 200010#define LL __int64#define inf 0x3f3f3f3f#define lson l,mid,ans<<1#define rson mid+1,r,ans<<1|1#define getMid (l+r)>>1#define movel ans<<1#define mover ans<<1|1using namespace std;const LL mod = 1e9 + 7;const double eps = 1e-9;struct node { int flag[2]; void init(int a, int b) { flag[0] = a;//存st flag[1] = b;//存ol }}sum[N << 2];//线段树主体int n, m, mi;vector<int> v;int st[N], ol[N], y[N];map<int, int>mapp;struct nope { int x, y; void get() { scanf("%d %d", &x, &y); } bool operator<(const nope&b)const{ return x<b.x; }}point[N];struct Segment__Tree { int x, y; void pushDown(int ans) { for (int i = 0; i < 2; i++) { sum[movel].flag[i] += sum[ans].flag[i]; sum[mover].flag[i] += sum[ans].flag[i]; sum[ans].flag[i] = 0; } } void build(int l, int r, int ans) { sum[ans].init(0, 0); if (l == r) { sum[ans].init(st[l], ol[l]); return; } int mid = getMid; build(lson); build(rson); } void solve(int l, int r, int ans, int &mi,int &mx,int pos) { if (l == r) { mi = sum[ans].flag[0]; mx = sum[ans].flag[1]; return; } pushDown(ans); int mid = getMid; if (pos <= mid) { return solve(lson, mi, mx, pos); } else { return solve(rson, mi, mx, pos); } } void updata(int l, int r, int ans, int type, int nums) { if (l >= x&&r <= y) { sum[ans].flag[type] += nums; return; } pushDown(ans); int mid = getMid; if (mid >= x) { updata(lson, type, nums); } if (mid < y) { updata(rson, type, nums); } }};int main() { Segment__Tree tree; while (~scanf("%d", &n) && n) { v.clear(); mapp.clear(); m = mi = 0; for (int i = 0; i < n; i++) { point[i].get(); y[i] = point[i].y; } sort(y, y + n); sort(point, point + n); mapp[y[0]] = 0; for (int i = 0; i < n; i++) {//离散化 if (y[m] != y[i]) { st[m] = n - i;//存高于该点y坐标有多少个点 y[++m] = y[i]; ol[m] = i;//存低于该点y坐标有多少个点 mapp[y[m]] = m; } } st[m] = 0; tree.build(0, m, 1); int id1 = 0; int id2 = 0; while (id1 < n) { id2 = id1; while (point[id1].x == point[id2].x) {//先给x轴相同的点-1 if (point[id2].y != y[0]) { tree.x = 0; tree.y = mapp[point[id2].y] - 1;//第二象限,ol减分 tree.updata(0, m, 1, 0, -1); } if (point[id2].y != y[m]) { tree.x = mapp[point[id2].y] + 1;//第四象限,ol减分 tree.y = m; tree.updata(0, m, 1, 1, -1); } if (++id2 >= n) break; } int mii = n, mxx = 0; for (int i = id1; i < id2; i++) { int tmp1, tmp2; tree.solve(0, m, 1, tmp1, tmp2, mapp[point[i].y]);//查询point[i]st,ol的得分 mii = min(mii, tmp1);//st的得分 mxx = max(mxx, tmp2);//ol的得分 } if (mii == mi) { v.push_back(mxx); } else if (mii > mi) { mi = mii; v.clear(); v.push_back(mxx); } for (int i = id1; i < id2; i++) { if (point[i].y != y[0]) { tree.x = 0; tree.y = mapp[point[i].y] - 1;//第三象限,st加分 tree.updata(0, m, 1, 1, 1); } if (point[i].y != y[m]) { tree.x = mapp[point[i].y] + 1;//第一象限,st加分 tree.y = m; tree.updata(0, m, 1, 0, 1); } } id1 = id2; } sort(v.begin(), v.end()); int len = unique(v.begin(), v.end()) - v.begin(); printf("Stan: %d; Ollie:", mi); for (int i = 0; i < len; i++) printf(" %d", v[i]); printf(";\n"); } return 0;}
阅读全文
0 0
- HDU 1156 Brownie Points II
- poj2464 Brownie Points II
- poj 2464 Brownie Points II
- HDU 1152 Brownie Points I
- hdu 1152 Brownie Points I
- hdu 1152 Brownie Points I
- POJ_2464 Brownie Points II 线段树
- poj2464 Brownie Points II 树状数组
- UVA 10869 - Brownie Points II(树状数组)
- uva 10869 - Brownie Points II(树状数组)
- UVA10869 - Brownie Points II(线段树)
- POJ 2464 Brownie Points II --树状数组
- poj 2464 Brownie Points II 树状数组
- Brownie Points II - POJ 2464 线段树
- 【数学 象限】HDU 1152 Brownie Points I
- POJ 2464 Brownie Points II 树状数组||线段树
- 线段树专题:poj 2464 Brownie Points II
- poj 2464 Brownie Points II (扫描线)
- ##* %%* linux变量处理
- CodeForces
- HDU1021(规律题)
- ASP.NET、.NET和C#的关系
- yolo v2之车牌检测后续识别字符(二)
- HDU 1156 Brownie Points II
- POJ2243 Knight Moves(A*算法)
- An error occurred while collecting items to be installed session context was:(profile=epp.package.je
- Hive的collect_set使用详解
- ListView保存并还原焦点
- Python笔记:迭代器、生成器、修饰器
- 前端工程师必须收藏的 CSS 资源大全
- 热血沸腾的小文章,总能给我鼓励
- 迅捷CAD转换器怎么把pdf文件转为CAD文件