POJ 2464 Brownie Points II 树状数组+扫描线

题意奇葩的一笔,本质上就是一个复杂统计,智商低下的我想不出来只好去搜了题解

#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <set>
#include <vector>
#include <string>
#include <queue>
#include <deque>
#include <bitset>
#include <list>
#include <cstdlib>
#include <climits>
#include <cmath>
#include <ctime>
#include <algorithm>
#include <stack>
#include <sstream>
#include <numeric>
#include <fstream>
#include <functional>

using namespace std;

#define MP make_pair
#define PB push_back
typedef long long LL;
typedef unsigned long long ULL;
typedef vector<int> VI;
typedef pair<int,int> pii;
const int INF = INT_MAX / 3;
const double eps = 1e-8;
const LL LINF = 1e17;
const double DINF = 1e60;
const int maxn = 2e5 + 10;

struct Point {
    int x,y;
    Point(int x = 0,int y = 0): x(x),y(y) {}
    bool operator < (const Point &p) const {
        return x < p.x;
    }
};

int n,numy[maxn],ky;
int Cleft[maxn],Cright[maxn];
int Stan,Ollie[maxn],Ocnt;
Point p[maxn];

inline int lowbit(int x) {
    return x & -x;
}

void addv(int *C,int v,int pos) {
    while(pos <= ky) {
        C[pos] += v; pos += lowbit(pos);
    }
}

int ask_(int *C,int pos) {
    int ret = 0;
    while(pos > 0) {
        ret += C[pos]; pos -= lowbit(pos);
    }
    return ret;
}

int ask(int *C,int l,int r) {
    if(l > r) return 0;
    return ask_(C,r) - ask_(C,l - 1);
}

int getID(int Val) {
    return lower_bound(numy,numy + ky,Val) - numy + 1;
}

int main() {
    while(scanf("%d",&n), n) {
        ky = 0;
        memset(Cleft,0,sizeof(Cleft));
        memset(Cright,0,sizeof(Cright));
        Ocnt = 0; Stan = -1;
        for(int i = 0;i < n;i++) {
            scanf("%d%d",&p[i].x,&p[i].y);
            numy[ky++] = p[i].y;
        }
        sort(p,p + n); sort(numy,numy + ky);
        ky = unique(numy,numy + ky) - numy;
        for(int i = 0;i < n;i++) addv(Cright,1,getID(p[i].y));
        for(int i = 0;i < n;i++) if(!i || p[i].x != p[i - 1].x) {
            for(int j = i;j < n && p[j].x == p[i].x;j++) {
                addv(Cright,-1,getID(p[j].y));
            }
            int colStan = INT_MAX,colOile = -1;
            for(int j = i;j < n && p[j].x == p[i].x;j++) {
                int nowStan,nowOile,nowpos = getID(p[j].y);
                nowStan = ask(Cleft,1,nowpos - 1) + ask(Cright,nowpos + 1,ky);
                nowOile = ask(Cleft,nowpos + 1,ky) + ask(Cright,1,nowpos - 1);
                if(nowOile > colOile) colOile = nowOile,colStan = INT_MAX;
                if(nowOile == colOile) colStan = min(colStan,nowStan);
            }
            if(colStan > Stan) {
                Stan = colStan; Ocnt = 0;
            }
            if(colStan == Stan) Ollie[Ocnt++] = colOile;
            for(int j = i;j < n && p[j].x == p[i].x;j++) {
                addv(Cleft,1,getID(p[j].y));
            }
        }
        sort(Ollie,Ollie + Ocnt);
        Ocnt = unique(Ollie,Ollie + Ocnt) - Ollie;
        printf("Stan: %d; Ollie:",Stan);
        for(int i = 0;i < Ocnt;i++) printf(" %d",Ollie[i]);
        puts(";");
    }
    return 0;
}

  

POJ 2464 Brownie Points II 树状数组+扫描线

时间: 2024-10-25 21:07:43

POJ 2464 Brownie Points II 树状数组+扫描线的相关文章

UVA 10869 - Brownie Points II(树状数组)

UVA 10869 - Brownie Points II 题目链接 题意:平面上n个点,两个人,第一个人先选一条经过点的垂直x轴的线,然后另一个人在这条线上穿过的点选一点作垂直该直线的线,然后划分出4个象限,第一个人得到分数为1,3象限,第二个人为二四象限,问第一个个人按最优取法,能得到最小分数的最大值,和这个值下另一个人的得分可能情况 思路:树状数组,可以枚举一点,如果能求出右上和左下点的个数就好办了,其实用一个树状数组,把y坐标离散化掉,然后记录进来,然后把点按x从左往右,每次删掉点后查询

poj 2464 Brownie Points II(扫描线)

题目链接:poj 2464 Brownie Points II 题意: 题意很迷啊. 有一些点,Stan选择某个点,经过这个点画一条竖线,Ollie选择一个经过这条直接的点画了条横线. Stan选一,三象限的点,Ollie选二.四象限的点. Stan的策略是,自己画一条竖线之后,Ollie有很多种选择,在所有选择中,Stan能获得数目的最小值的最大值,而Ollie的选择便 是让自己越多越好. 题解: 下面是cxlove dalao的题解: 首先对于某个方向离散化,我是按x排序,将y离散化. 建立

POJ 2828 poj 2828 Buy Tickets 【树状数组,已知前n项和为K,返回n值】

题目链接:http://poj.org/problem?id=2828 在一个队列中,一个人想要插队,告诉你每个新来的人会插在i个人后面,求出最后的队列. 如果我们用模拟的话,那么时间复杂度肯定是超了:想想,如果我们逆序,那么最后来的人的位置一定是固定的,这样的话,我们将问题转化成逆序扫描给出数据,插在i个人后面这个数据就变成了在这个人前面需要留出多少个空位.如此我们只需要用树状数组记录前n项总共有多少个空位,每扫描一个数据,就找出能使得他前面正好有i个空位. 这题用树状数组或者线段树都可以,今

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

Apple Tree Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 18623   Accepted: 5629 Description There is an apple tree outside of kaka's house. Every autumn, a lot of apples will grow in the tree. Kaka likes apple very much, so he has been

POJ 2299 Ultra-QuickSort (离散化+树状数组)

题目链接:POJ 2299 Ultra-QuickSort 求一串序列相邻连个元素交换多少后,是一串上升的序列. 思路:求该串序列的逆序数,数据比较大,要离散化. AC代码: #include<stdio.h> #include<string.h> #include<set> #include<map> #include<algorithm> #define ll __int64 using namespace std; const ll max

【POJ 1195】 Mobile phones (树状数组)

[POJ 1195] Mobile phones (树状数组) Mobile phones Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 16761   Accepted: 7713 Description Suppose that the fourth generation mobile phone base stations in the Tampere area operate as follows. The ar

poj3109树状数组+扫描线

题意:无限大的棋盘上,在横向和纵向上被包围的白子会变成黑子,求最终黑子个数? 分析: 首先这个棋盘十分的大,但已给黑点的个数为1e5,我们需要离散化,所谓的离散化就是数组下标的重新定义. 这里给出离散化函数,返回的是离散化后数组的个数 1 int compress(int *p,int N) 2 { 3 vector<int> ps(N); 4 for (int i = 0; i < N; ++i)ps[i] = p[i]; 5 sort(ps.begin(), ps.end()); 6

UVA 10869 - Brownie Points II(树阵)

UVA 10869 - Brownie Points II 题目链接 题意:平面上n个点,两个人,第一个人先选一条经过点的垂直x轴的线.然后还有一个人在这条线上穿过的点选一点作垂直该直线的线,然后划分出4个象限,第一个人得到分数为1.3象限,第二个人为二四象限.问第一个个人按最优取法,能得到最小分数的最大值,和这个值下还有一个人的得分可能情况 思路:树状数组,能够枚举一点,假设能求出右上和左下点的个数就好办了,其有用一个树状数组,把y坐标离散化掉,然后记录进来,然后把点按x从左往右,每次删掉点后

POJ 2155 Matrix(二维树状数组,绝对具体)

Matrix Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 20599   Accepted: 7673 Description Given an N*N matrix A, whose elements are either 0 or 1. A[i, j] means the number in the i-th row and j-th column. Initially we have A[i, j] = 0 (1