题意: 有点迷。有一些点,Stan先选择某个点,经过这个点画一条竖线,Ollie选择一个经过这条直接的点画一条横线。Stan选这两条直线分成的左下和右上部分的点,Ollie选左上和右下部分的点。Stan画一条竖线之后,Ollie有很多种选择,在所有选择中,Stan能获得 “分数最小值的最大值” ,而Ollie的选择便是让自己越多越好。问最后Stan最多能得到的分数是多少,以及在这种情况下Ollie能得到的分数有多少种可能。

解法: 因为Stan先选,然后主动权在Ollie手中,Ollie会优先让自己得到更多的分数,然后再考虑让Stan得到的分数最小。然后才能求得Stan得到的“分数最小值的最大值”。

既然是Stan先选,那么我们最好按x从小到大排序,y坐标离散,依次处理,又因为在同一条竖线可能有很多店,所以直到坐标变化时才来同一处理那些横坐标相同的点,Ollie在这些点对应的纵坐标中做选择,使达到上述说的效果。

由于竖线往右移,那么维护两个树状数组,一个是当前竖线右边的点的情况,一个是左边的。然后扫过去,遇到p[i].x!=p[i-1].x时,就可以处理前面的一个或多个横坐标相同的点了,然后按上述说的做就行了。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <set>
using namespace std;
#define N 200007 struct node{
int x,y;
}p[N];
int n,maxi;
int L[N],R[N],a[N],b[N];
int lowbit(int x) { return x&-x; }
int cmp1(node ka,node kb) { return ka.x < kb.x; }
int cmp2(node ka,node kb) { return ka.y < kb.y; } void modify(int *c,int x,int val)
{
while(x <= maxi)
c[x] += val, x += lowbit(x);
} int getsum(int *c,int x)
{
int res = ;
while(x > ) { res += c[x]; x -= lowbit(x); }
return res;
} int main()
{
int i,j;
while(scanf("%d",&n)!=EOF && n)
{
maxi = ;
for(i=;i<=n;i++)
scanf("%d%d",&p[i].x,&p[i].y);
sort(p+,p+n+,cmp1); //....离散
for(i=;i<=n;i++)
{
if(p[i].x == p[i-].x) a[i] = a[i-];
else a[i] = a[i-]+;
}
for(i=;i<=n;i++) p[i].x = a[i];
sort(p+,p+n+,cmp2);
for(i=;i<=n;i++)
{
if(p[i].y == p[i-].y) b[i] = b[i-];
else b[i] = b[i-]+;
maxi = max(maxi,b[i]);
}
for(i=;i<=n;i++) p[i].y = b[i]; //离散....
memset(L,,sizeof(L));
memset(R,,sizeof(R));
for(i=;i<=n;i++)
modify(R,p[i].y,);
int Stan = -,ollie,stan,start = ;
sort(p+,p+n+,cmp1);
p[n+].x = -,p[n+].y = -;
set<int> Ollie;
for(i=;i<=n+;i++)
{
if(p[i].x == p[i-].x) continue;
stan = ollie = -;
for(j=start;j<i;j++)
modify(R,p[j].y,-);
for(j=start;j<i;j++)
{
int pos = p[j].y;
int STAN = getsum(R,maxi)-getsum(R,pos)+getsum(L,pos-); //右上+左下
int OLLIE = getsum(L,maxi)-getsum(L,pos)+getsum(R,pos-); //左上+右下
if(OLLIE == ollie) stan = min(stan,STAN); //在保证Ollie取最多的情况下让Stan得分最少
else if(OLLIE > ollie) stan = STAN, ollie = OLLIE;
}
if(stan > Stan) Stan = stan, Ollie.clear(), Ollie.insert(ollie);
else if(stan == Stan) Ollie.insert(ollie);
for(j=start;j<i;j++)
modify(L,p[j].y,);
start = i;
}
printf("Stan: %d; Ollie:",Stan);
for(set<int>::iterator it=Ollie.begin();it!=Ollie.end();it++)
printf(" %d",*it);
printf(";\n");
}
return ;
}

POJ 2464 Brownie Points II --树状数组的更多相关文章

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

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

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

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

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

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

  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. POJ 2155 Matrix(二维树状数组,绝对具体)

    Matrix Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 20599   Accepted: 7673 Descripti ...

  7. poj 3321:Apple Tree(树状数组,提高题)

    Apple Tree Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 18623   Accepted: 5629 Descr ...

  8. POJ 2299 Ultra-QuickSort 逆序数 树状数组 归并排序 线段树

    题目链接:http://poj.org/problem?id=2299 求逆序数的经典题,求逆序数可用树状数组,归并排序,线段树求解,本文给出树状数组,归并排序,线段树的解法. 归并排序: #incl ...

  9. poj 3321 Apple Tree(一维树状数组)

    题目:http://poj.org/problem?id=3321 题意: 苹果树上n个分叉,Q是询问,C是改变状态.... 开始的处理比较难,参考了一下大神的思路,构图成邻接表 并 用DFS编号 白 ...

随机推荐

  1. 由简入繁实现Jquery树状结构

    在项目中,我们经常会需要一些树状结构的样式来显示层级结构等,比如下图的样式,之前在学.net的时候可以直接拖个服务端控件过来直接使用非常方便.但是利用Jquery的一些插件,也是可以实现这些效果的,比 ...

  2. 解决SlidingMenu和SwipeBackLayout右滑事件冲突问题

    SwipeBackLayout向右滑动关闭当前Activity,SlidingMenu向右滑动则是打开menu部分.在同一个Activity中,当SlidingMenu处于打开状态时,此时向右滑动,事 ...

  3. [Xamarin.Android] 自定义控件

    [Xamarin.Android] 自定义控件 前言 软件项目开发的过程中,免不了遇到一些无法使用内建控件就能满足的客户需求,例如:时速表.折线图...等等.这时开发人员可以透过自定义控件的方式,为项 ...

  4. VS2010中重命名项目

    通常,在项目开发初始,一般都是先做一个Demo,以方便进行修改设计.演示等,这可能导致项目命名并不符合最后的规范,则需要修改项目名称.VS没有推出这方面针对性的功能,网友们也纷纷自己写了软件. 方案一 ...

  5. Log4net中的调错

    在使用log4net时,感觉最麻烦的就是配置文件了,为了使用方便,我不得不先准备好一个完整的配置文件方案,测试了输出到文本.控制台.windows事件.SQL Server数据库都没有问题,但输出到o ...

  6. 解决SSIS中的脚本任务无法调试的问题

    开发环境:操作系统环境为Win7 64Bit,数据库为SQLServer2008R2 问题现象:在SSIS的项目工程中,新建Package包,新建脚本任务,编写脚本程序以后,设置断点无法调试(Debu ...

  7. git学习笔记2

    工作区和暂存区 Git和其他版本控制系统如SVN的一个不同之处就是有暂存区的概念. 先来看名词解释. 工作区(Working Directory) 就是你在电脑里能看到的目录,比如我的github文件 ...

  8. Eclipse下link方式安装插件

    一.eclipse安装位置和存放文件位置 eclipse安装位置:D:\ProgramFile\eclipse存放文件:D:\mydep 二.下载插件 这里下载的是PropertiesEditor解压 ...

  9. Retrofit源码设计模式解析(下)

    本文将接着<Retrofit源码设计模式解析(上)>,继续分享以下设计模式在Retrofit中的应用: 适配器模式 策略模式 观察者模式 单例模式 原型模式 享元模式 一.适配器模式 在上 ...

  10. Mac OS X上安装 Ruby运行环境

    环境   对于新入门的开发者,如何安装 Ruby和Ruby Gems 的运行环境可能会是个问题,本页主要介绍如何用一条靠谱的路子快速安装 Ruby 开发环境.此安装方法同样适用于产品环境! 系统需求 ...