UVA10869 - Brownie Points II(线段树)

题目链接

题目大意:平面上有n个点,Stan和Ollie在玩游戏,游戏规则是:Stan先画一条竖直的线作为y轴,条件是必需要经过这个平面上的某一点,而ollie则画x轴,可是要在Stany画的y轴上经过的点中随意选择一点来作为原点画x轴。然后这个平面就被划分为4个象限,轴上的点都不算,1,3象限的点的个数就是Stan的得分,2,4就是ollie的得分。问Stan每画一条y轴,每条轴上都有个得分的最小值,求这些最小值中的最大值,而且输出这时ollie的得分。

解题思路:将y轴离散化建树,希望每次枚举一个点就能够得到这个点的Stan的得分。从左往右,从上往下处理每一个点,通过线段树能够得到y高度上的点的个数,就是第一象限的得分。然后每次查询完一个点就要将这个点在线段树中删掉。同理得到第三象限的得分。这题还要输出ollie的得分,而且要按顺序,用set来存储。

代码:

#include <cstdio>
#include <cstring>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <iostream> using namespace std; const int maxn = 2e5;
#define lson(x) (x<<1)
#define rson(x) ((x<<1) | 1) int n;
vector<int> pos;
map<int, int>x, y;
set<int> score, vec; struct Point { int x, y, score;
}p[maxn]; int cmp_x (const Point &a, const Point &b) {
if (a.x == b.x)
return a.y > b.y;
return a.x < b.x;
} struct Node { int l, r, v, addv;
void set (int l, int r, int addv, int v) { this->l = l;
this->r = r;
this->v = v;
this->addv = addv;
}
}node[4 * maxn + 5]; void add_node (int u, int addv) { node[u].addv += addv;
node[u].v += (node[u].r - node[u].l + 1) * addv;
} void pushdown (int u) { if (node[u].addv) {
add_node(lson(u), node[u].addv);
add_node(rson(u), node[u].addv);
}
} void pushup (int u) { node[u].set (node[lson(u)].l, node[rson(u)].r, 0, node[lson(u)].v + node[rson(u)].v);
} void build (int u, int l, int r) { if (l == r) { node[u].set (l, r, 0, y[pos[l]]);
return ;
}
int m = (l + r)>>1;
build (lson(u), l, m);
build (rson(u), m + 1, r);
pushup(u);
} void update (int u, int l, int r, int add) { if (node[u].l >= l && node[u].r <= r) {
add_node(u, add);
return;
} pushdown(u);
int m = (node[u].l + node[u].r)>>1;
if (l <= m)
update (lson(u), l, r, add);
if (r > m)
update (rson(u), l, r, add);
pushup(u);
} int query (int u, int l, int r) { if (node[u].l >= l && node[u].r <= r)
return node[u].v; pushdown(u);
int m = (node[u].l + node[u].r)>>1;
int ans = 0;
if (l <= m)
ans += query(lson(u), l, r);
if (r > m)
ans += query(rson(u), l, r);
pushup(u);
return ans;
} void init () { x.clear();
y.clear();
pos.clear(); for (int i = 0; i < n; i++) { scanf ("%d%d", &p[i].x, &p[i].y);
p[i].score = 0;
x[p[i].x]++;
y[p[i].y]++;
pos.push_back(p[i].y);
} sort (pos.begin(), pos.end());
sort (p, p + n, cmp_x);
pos.erase(unique (pos.begin(), pos.end()), pos.end());
} void solve_rtop () { int x;
build(1, 0, (int)pos.size() - 1);
for (int i = 0; i < n; i++) { x = lower_bound(pos.begin(), pos.end(), p[i].y) - pos.begin();
if (x + 1 <= pos.size() - 1) {
p[i].score += query(1, x + 1, pos.size() - 1);
//printf ("%d %d %d\n", p[i].x, p[i].y, x);
}
update (1, x, x, -1);
}
} void solve_lboutom () { int x;
build(1, 0, (int)pos.size() - 1);
for (int i = n - 1; i >= 0; i--) { x = lower_bound(pos.begin(), pos.end(), p[i].y) - pos.begin();
if (x - 1 >= 0) {
p[i].score += query (1, 0, x - 1);
//printf ("%d %d %d\n", p[i].x, p[i].y, p[i].score);
}
update (1, x, x, -1);
}
} void add_ans (int tmp) { for (set<int>::iterator it = vec.begin(); it != vec.end(); it++)
score.insert(n - tmp - x[p[*it].x] - y[p[*it].y] + 1);
} void solve () { init();
solve_lboutom();
solve_rtop();
score.clear();
vec.clear(); int ans = -1;
int tmp = p[0].score;
int pre = p[0].x; for (int i = 0; i < n; i++) { if (pre == p[i].x) {
if (tmp == p[i].score)
vec.insert(i);
else if (tmp > p[i].score) {
vec.clear();
vec.insert(i);
tmp = p[i].score;
}
} else { if (ans <= tmp) {
if (ans < tmp)
score.clear();
add_ans(tmp);
}
ans = max (ans, tmp);
tmp = p[i].score;
pre = p[i].x;
vec.clear();
vec.insert(i);
}
} if (ans <= tmp) {
if (ans < tmp)
score.clear();
add_ans(tmp);
}
ans = max (ans, tmp); printf("Stan: %d; Ollie:", ans);
for (set<int>::iterator it = score.begin(); it != score.end(); it++)
printf(" %d", *it);
printf(";\n");
} int main () { while (scanf ("%d", &n) && n) {
solve();
}
return 0;
}

UVA10869 - Brownie Points II(线段树)的更多相关文章

  1. HDOJ-1156 Brownie Points II 线段树/树状数组(模板)

    http://acm.hdu.edu.cn/showproblem.php?pid=1156 在一张二位坐标系中,给定n个点的坐标,玩一个划线游戏(线必须穿过点),Stan先手画一条垂直的线,然后Ol ...

  2. POJ 2464 Brownie Points II(树状数组)

    一开始还以为对于每根竖线,只要与过了任意一点的横线相交都可以呢,这样枚举两条线就要O(n^2),结果发现自己想多了... 其实是每个点画根竖线和横线就好,对于相同竖线统计(一直不包含线上点)右上左下总 ...

  3. POJ 2464 Brownie Points II (树状数组,难题)

    题意:在平面直角坐标系中给你N个点,stan和ollie玩一个游戏,首先stan在竖直方向上画一条直线,该直线必须要过其中的某个点,然后ollie在水平方向上画一条直线,该直线的要求是要经过一个sta ...

  4. POJ - 2464 Brownie Points II 【树状数组 + 离散化】【好题】

    题目链接 http://poj.org/problem?id=2464 题意 在一个二维坐标系上 给出一些点 Stan 先画一条过一点的水平线 Odd 再画一条 过Stan那条水平线上的任一点的垂直线 ...

  5. UVA 10869 - Brownie Points II(树阵)

    UVA 10869 - Brownie Points II 题目链接 题意:平面上n个点,两个人,第一个人先选一条经过点的垂直x轴的线.然后还有一个人在这条线上穿过的点选一点作垂直该直线的线,然后划分 ...

  6. hdu 1156 && poj 2464 Brownie Points II (BIT)

    2464 -- Brownie Points II Problem - 1156 hdu分类线段树的题.题意是,给出一堆点的位置,stan和ollie玩游戏,stan通过其中一个点画垂线,ollie通 ...

  7. LightOJ 1089 - Points in Segments (II) 线段树区间修改+离散化

    http://www.lightoj.com/volume_showproblem.php?problem=1089 题意:给出许多区间,查询某个点所在的区间个数 思路:线段树,由于给出的是区间,查询 ...

  8. Day6 - E - Brownie Points II POJ - 2464

    Stan and Ollie play the game of Odd Brownie Points. Some brownie points are located in the plane, at ...

  9. CDOJ 1259 昊昊爱运动 II 线段树+bitset

    昊昊爱运动 II 昊昊喜欢运动 他N天内会参加M种运动(每种运动用一个[1,m]的整数表示) 现在有Q个操作,操作描述如下 昊昊把第l天到第r天的运动全部换成了x(x∈[1,m]) 问昊昊第l天到第r ...

随机推荐

  1. Python中的深浅拷贝,赋值及引用

    简单来说,若对象a中存的是列表或字典等可变对象,b对a的浅拷贝只是对对象第一层的复制,修改b第二层的元素仍然会影响两个对象. 深拷贝则是不会影响原来的对象. import copy.copy() 浅拷 ...

  2. Unity 音乐播放全局类

    今天晚了LOL, 发现里面的声音系统做得很不错,于是最近就写了一份反正以后也用的到,2D音乐全局播放. 项目跟PoolManager对象池插件结合了. 解决的问题: 1. 已经播放的声音,可以马上暂停 ...

  3. poj1080--Human Gene Functions(dp:LCS变形)

    Human Gene Functions Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 17206   Accepted:  ...

  4. 单调队列-hdu-3415-Max Sum of Max-K-sub-sequence

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3415 题目大意: 给n个数凑成环状,求某一区间,使得该区间长度不超过k,且总和最大. 解题思路: 区 ...

  5. NGUI研究之制作转圈的技能CD特效

     昨天想做一个技能CD转圈的特效,花了大把的时间去用meshRender组件想通过三角形依据数学算法来绘制一个圆形的网格.通过动态绘制圆形网格的方法来实现技能CD特效.奶奶的昨天我研究了一晚上,最 ...

  6. C程序设计语言(K&R)笔记

    1.表达式中float类型的操作数不会自动转换为double类型.一般来说,数学函数(如math.h)使用双精度类型的变量.使用float类型主要是为了在使用较大数组时节省存储空间,有时也为了节省机器 ...

  7. tail

    tail用于显示指定文件末尾内容,不指定文件时,作为输入信息进行处理.常用查看日志文件. -f 循环读取 -q 不显示处理信息 -v 显示详细的处理信息 -c<数目> 显示的字节数 -n& ...

  8. kvm 图形化安装

    为了再后续查看方便,我还是完整的记录kvm图形化安装. 介于网络环境的原因,我选择NAT. 2,安装kvm前的准备工作 2.1 关闭防火墙  setenforce 0    vi /etc/sysco ...

  9. ios ColorLUT滤镜

    通过这种方格图片实现滤镜 代码: "CIFilter+ColorLUT.h" "CIFilter+ColorLUT.m" #import "CIFil ...

  10. java 成神之路

    一.基础篇 1.1 JVM 1.1.1. Java内存模型,Java内存管理,Java堆和栈,垃圾回收 http://www.jcp.org/en/jsr/detail?id=133 http://i ...