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

Stan 先画一条过一点的水平线
Odd 再画一条 过Stan那条水平线上的任一点的垂直线

Stan的得分为右上角区域的点数+左下角区域的点数
Ollie的得分为左上角区域的点数+右下角区域的点数

AC代码

#pragma comment(linker, "/STACK:102400000,102400000")

#include <cstdio>
#include <cstring>
#include <cctype>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <deque>
#include <vector>
#include <queue>
#include <string>
#include <map>
#include <stack>
#include <set>
#include <list>
#include <bitset>
#include <assert.h>
#include <numeric>
#include <sstream>
#include <iomanip>
#include <limits>
//#include <xfunctional>   // greater less
//#include <unordered_map>
//#include <unordered_set>

using namespace std;

namespace Dup4
{
typedef long long ll;
typedef long double ld;
typedef long double ld;
typedef unsigned long long ull;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef pair <ll, int> pli;
typedef vector <int> vi;
typedef vector <ll> vll;
typedef vector < vi > vvi;

#define fi first
#define se second
#define pb push_back
#define gc getchar
#define pc putchar
#define p32 pc(' ')
#define p10 pc('\n')
#define L(on) ((on)<<1)
#define R(on) (L(on) | 1)
//#define gcd(a,b) __gcd(a,b)
#define lowbit(x) ((x)&(-x))
#define mkp(a, b) make_pair(a, b)
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define CLR(a, b) memset(a, (b), sizeof(a));
#define random(a,b) ((a)+rand()%((b)-(a)+1))
#define syn_close ios::sync_with_stdio(false); cin.tie(0);

//__builtin_popcount(i) // 返回一个数中二进制形式中1的个数

{
int x = 0, f = 1; char c = gc();
for (; !isdigit(c); c = gc()) f ^= (c == '-');
for (; isdigit(c); c = gc()) x = x * 10 + (c - '0');
return x * (f ? 1 : -1);
}

template <typename T>
{
x = 0; int f = 1; char c = gc();
for (; !isdigit(c); c = gc()) f ^= (c == '-');
for (; isdigit(c); c = gc()) x = x * 10 + (c - '0');
x *= f ? 1 : -1;
}

template <typename T>
inline void write(T x)
{
if (!x) { pc(48); return; }
if (x < 0) x = -x, pc('-');
int bit[20], i, p = 0;
for (; x; x /= 10) bit[++p] = x % 10;
for (i = p; i; --i) pc(bit[i] + 48);
}

//仅限于正整数读入

inline char nc()
{
static char buf[100000], *i = buf, *j = buf;
return i == j && (j = (i = buf) + fread(buf, 1, 100000, stdin), i == j) ? EOF : *i++;
}

template <typename T>
{
char ch = nc(); sum = 0;
while (!(ch >= '0' && ch <= '9')) ch = nc();
while (ch >= '0' && ch <= '9') sum = sum * 10 + ch - 48, ch = nc();
}

template <typename T>
inline T gcd(T a, T b)
{
while (b ^= a ^= b ^= a %= b);
return a;
}

#ifdef LOCAL
#define gets gets_s
#define sp system("pause");
#define bug puts("***bug***");
#endif

#ifdef ONLINE_JUDGE
#define sp
#define bug
#endif

const double PI = acos(-1.0);
const double EI = exp(1.0);
const double eps = 1e-8;

const int INF = 0x3f3f3f3f;
const ll INFLL = 0x3f3f3f3f3f3f3f3fll;
}

using namespace Dup4;

namespace FastIO
{
// 只可读入 正整数，单字符
#define BUF_SIZE 10000005
bool IOerror = false;
inline char NC()
{
static char buf[BUF_SIZE], *p1 = buf + BUF_SIZE, *pend = buf + BUF_SIZE;
if (p1 == pend)
{
p1 = buf;
pend = buf + fread(buf, 1, BUF_SIZE, stdin);
if (pend == p1)
{
IOerror = true;
return -1;
}
}
return *p1++;
}

inline bool blank(char ch)
{
return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t';
}

{
char ch;
while (blank(ch = NC()));
if (IOerror)
{
x = -1;
return;
}
x = ch;
}

template <typename T>
{
char ch;
while (blank(ch = NC()));
if (IOerror)
{
x = -1;
return;
}
for (x = ch - '0'; isdigit(ch = NC()); x = x * 10 + ch - '0');
}
#undef BUF_SIZE
}

using namespace FastIO;

const int maxn = (int)2e5 + 10;
const int Maxn = (int)1e7 + 100;
const int MOD = (int)1e8 +7;

int n;
int y[maxn];

struct node
{
int x, y;
void scan()
{
}
bool operator < (const node& r) const
{
return x < r.x || x == r.x && y < r.y;
}
}cor[maxn];

bool Input()
{
if (n = read(), n == 0) return false;
for (int i = 1; i <= n; i++)
cor[i].scan(), y[i] = cor[i].y;
sort(y + 1, y + 1 + n);
int pos = unique(y + 1, y + 1 + n) - y - 1;
//cout << pos << endl;
for (int i = 1; i <= n; i++)
{
int it = lower_bound(y + 1, y + 1 + pos, cor[i].y) - y;
cor[i].y = it;
//printf("%d%c", cor[i].y, " \n"[i == n]);
}
return true;
}

int a[maxn];

{
for (int i = x; i < maxn; i += lowbit(i))
a[i] ++;
}

int sum(int x)
{
int ans = 0;
for (int i = x; i > 0; i -= lowbit(i))
ans += a[i];
return ans;
}

int ans_Stan[maxn], ans_Ollie[maxn];
bool vis[maxn];

void Solve()
{
CLR(a, 0); CLR(vis, false);
sort(cor + 1, cor + 1 + n);
int tot = 0; add(cor[1].y); ans_Stan[1] = 0; ans_Ollie[1] = 0;
for (int i = 2; i <= n; i++)
{
if (cor[i].x == cor[i - 1].x)
tot++;
else
tot = 0;
ans_Stan[i] = sum(cor[i].y - 1) - tot;
ans_Ollie[i] = i - sum(cor[i].y);
}
tot = 0; CLR(a, 0); add(cor[n].y);
for (int i = n - 1; i >= 1; i--)
{
if (cor[i].x == cor[i + 1].x)
tot++;
else
tot = 0;
ans_Stan[i] += (n - i) - sum(cor[i].y) - tot;
ans_Ollie[i] += sum(cor[i].y - 1);
}
int index = 1, MMax = 1, Max = 0;
//for (int i = 1; i <= n; i++)
//  printf("%d %d %d %d\n", ans_Stan[i], ans_Ollie[i], cor[i].x, cor[i].y);
for (int i = 2; i <= n; i++)
{
if (cor[i].x == cor[i - 1].x)
{
if (ans_Ollie[i] > ans_Ollie[MMax] || ans_Ollie[i] == ans_Ollie[MMax] && ans_Stan[i] < ans_Stan[MMax])
MMax = i;
}
else
{
//printf("%d %d\n", i, MMax);
for (int j = index; j < i; j++)
{
if (j == MMax)
{
Max = max(Max, ans_Stan[j]);
continue;
}
//printf("%d %d\n", cor[j].x, cor[j].y - 100000);
vis[j] = true;
}
index = i, MMax = i;
}
if (i == n)
{
for (int j = index; j <= n; j++)
{
if (j == MMax)
{
Max = max(Max, ans_Stan[j]);
continue;
}
vis[j] = true;
}
}
}
//cout << Max << endl;
vector <int> ans;
for (int i = 1; i <= n; i++)
{
if (ans_Stan[i] == Max && vis[i] == false)
{
//printf("%d %d\n", cor[i].x, cor[i].y - 100000);
ans.pb(ans_Ollie[i]);
}
}
printf("Stan: %d; Ollie:", Max);
sort(all(ans));
for (int i = 0, len = ans.size(); i < len; i++)
if (i == 0 || ans[i] != ans[i - 1])
printf(" %d", ans[i]);
puts(";");
}

void Run()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
//freopen("1.out", "w+", stdout);
#endif

while (Input())
Solve();

#ifdef LOCAL
fclose(stdin);
//fclose(stdout);
#endif
}

int main()
{
Run();
return 0;
}

/*

*/