题目描述

平面上有n个点,每个点有一种颜色。对于某一条线段,选择所有其上方或下方的点。求:在不包含所有颜色的点的前提下,选择的点数最多是多少。(本题中如果存在某颜色没有相应的点,那么选择任何线段都不算做包含所有颜色)

输入

包含多组测试数据,第一行输入一个正整数 T 表示测试数据组数。

接下来 T 组测试数据,对于每组测试数据,第一行输入两个正整数 N、K,分别表示点数和颜色数。
接下来 N 行,每行描述一个点,前两个数 x, y (|x|, |y| ≤ 2^30 - 1) 描述点的位置,最后一个数 z (1 ≤ z ≤ k) 描述点的颜色。
对于 100% 的数据,N ≤ 100000,K ≤ 100000,T ≤ 3

输出

对于每组数据在一行内输出一个非负整数 ans,表示答案

样例输入

1
10 3
1 2 3
2 1 1
2 4 2
3 5 3
4 4 2
5 1 2
6 3 1
6 7 1
7 2 3
9 4 2

样例输出

5


题解

STL-set+树状数组

(选择上面和下面的情况相同,不妨设只能选择上面来分析)

考虑:不包含所有颜色,就是存在某一种颜色没有被包含。

因此我们枚举某一种颜色,由于矩形越大越好,因此求的就是不包含该颜色的所有极大矩形。

我们把所有点按照纵坐标从大到小排序,然后对于某一个点,如果选出以其为下边界的矩形,它左边界的范围就是它的横坐标的前驱,右边界的范围就是后继(这两个便捷范围取不到)

我们使用set维护横坐标的前驱后继即可得到所有的极大矩形。然后要求的就是矩形包含的点的面积。注意到这里按照纵坐标排了序,因此直接使用离散化+树状数组求横坐标在某范围内的点的个数即可。

注意纵坐标相同的要先计算再插入。

还有一种情况:线段纵坐标没有限制(矩形卡在两个横坐标相邻的同种点之间),在set中计算一遍即可。

对于线段下面的情况同理。

时间复杂度$O(n\log n)$

#include <set>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 100010
using namespace std;
set<int> s[N];
struct data
{
int x , y , z;
bool operator<(const data &a)const {return y < a.y;}
}a[N];
int n , m , v[N] , f[N] , ans;
inline void add(int x)
{
int i;
for(i = x ; i <= n ; i += i & -i) f[i] ++ ;
}
inline int query(int x)
{
int i , ans = 0;
for(i = x ; i ; i -= i & -i) ans += f[i];
return ans;
}
void solve()
{
int i , j , k;
set<int>::iterator it;
memset(f , 0 , sizeof(f));
for(i = 1 ; i <= m ; i ++ ) s[i].clear() , s[i].insert(0) , s[i].insert(n + 1);
for(i = j = 1 ; i <= n ; i = j)
{
while(j <= n && a[j].y == a[i].y) j ++ ;
for(k = i ; k < j ; k ++ ) ans = max(ans , query(*s[a[k].z].lower_bound(a[k].x) - 1) - query(*--s[a[k].z].upper_bound(a[k].x)));
for(k = i ; k < j ; k ++ ) add(a[k].x) , s[a[k].z].insert(a[k].x);
}
for(i = 1 ; i <= m ; i ++ )
for(it = s[i].begin() ; *it != n + 1 ; )
j = *it , ans = max(ans , query(*++it - 1) - query(j));
}
int main()
{
int T , i;
scanf("%d" , &T);
while(T -- )
{
scanf("%d%d" , &n , &m);
for(i = 1 ; i <= n ; i ++ ) scanf("%d%d%d" , &a[i].x , &a[i].y , &a[i].z) , v[i] = a[i].x;
sort(a + 1 , a + n + 1) , sort(v + 1 , v + n + 1);
for(i = 1 ; i <= n ; i ++ ) a[i].x = lower_bound(v + 1 , v + n + 1 , a[i].x) - v;
ans = 0 , solve();
for(i = 1 ; i <= n >> 1 ; i ++ ) swap(a[i] , a[n - i + 1]);
solve();
printf("%d\n" , ans);
}
return 0;
}

【bzoj4548】小奇的糖果 STL-set+树状数组的更多相关文章

  1. Bzoj4548 小奇的糖果(链表+树状数组)

    题面 Bzoj 题解 很显然,我们只需要考虑单独取线段上方的情况,对于下方的把坐标取反再做一遍即可(因为我们只关心最终的答案) 建立树状数组维护一个横坐标区间内有多少个点,维护双向链表实现查询一个点左 ...

  2. 【BZOJ4548】小奇的糖果 set(链表)+树状数组

    [BZOJ4548]小奇的糖果 Description 有 N 个彩色糖果在平面上.小奇想在平面上取一条水平的线段,并拾起它上方或下方的所有糖果.求出最多能够拾起多少糖果,使得获得的糖果并不包含所有的 ...

  3. 【BZOJ-4548&3658】小奇的糖果&Jabberwocky 双向链表 + 树状数组

    4548: 小奇的糖果 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 103  Solved: 47[Submit][Status][Discuss] ...

  4. 【题解】BZOJ4548 小奇的糖果(树状数组)

    [题解]BZOJ4548 小奇的糖果(树状数组) 说在前面:我有个同学叫小奇,他有一个朋友叫达达,达达特爱地理和旅游,初中经常AK地理,好怀恋和他已经达达一起到当时初中附近许多楼盘的顶楼逛的时光... ...

  5. BZOJ4548 小奇的糖果

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000作者博客:http://www.cnblogs.com/ljh2000-jump/转 ...

  6. 【题解】 BZOJ4548 小奇的糖果

    本文同步在学弟ZCDHJ的个人博客发布,审核需要一段时间. 传送门 考虑题目中获得的糖果并不包含所有的颜色这句话,发现相当于我们可以直接选取某一个颜色强制不能选(这样子一定最优). 然后就可以考虑分开 ...

  7. 求序列A中每个数的左边比它小的数的个数(树状数组)

    给定一个有N个正整数的序列A(N<=10^5,A[i]<=10^5),对序列中的每一个数,求出序列中它左边比它小的数的个数. 思路:树状数组的经典应用(裸题) #include <i ...

  8. [CSP-S模拟测试]:小P的单调数列(树状数组+DP)

    题目描述 小$P$最近喜欢上了单调数列,他觉得单调的数列具有非常多优美的性质.经过小$P$复杂的数学推导,他计算出了一个单调增数列的艺术价值等于该数列中所有书的总和.并且以这个为基础,小$P$还可以求 ...

  9. BZOJ 4017 小 Q 的无敌异或 ( 树状数组、区间异或和、区间异或和之和、按位计贡献思想 )

    题目链接 题意 : 中文题 分析 : 首先引入两篇写的很好的题解 题解一.题解二 听说这种和异或相关区间求和的问题都尽量按位考虑 首先第一问.按二进制位计贡献的话.那么对于第 k 位而言 其贡献 = ...

  10. bzoj4548: 小奇的糖果 题解

    题目链接 题解 不包含所有颜色 就强制不选一个颜色 图中圆点颜色相同 矩形越大,包括的点一定不比其一小部分少 如图所示,最大矩形只有3种 离散化\(x\)坐标 然后按\(y\)排序 每次取出颜色的前驱 ...

随机推荐

  1. Angular : 基础语句说明, 响应式表单指令, 组件生命周期钩子

  2. Mysql基础3-数据操作语言DML-数据查询语言DQL

    主要: 数据操作语言DML 数据查询语言DQL 数据操作语言DML DML: Data Mutipulation Language 插入数据(增) 一般插入数据形式 1)形式1: insert [in ...

  3. Java学习笔记八:Java的流程控制语句之循环语句

    Java的流程控制语句之循环语句 一:Java循环语句之while: 生活中,有些时候为了完成任务,需要重复的进行某些动作.如参加 10000 米长跑,需要绕 400 米的赛道反复的跑 25 圈.在 ...

  4. Linux命令备忘录:mount用于加载文件系统到指定的加载点

    mount命令用于加载文件系统到指定的加载点.此命令的最常用于挂载cdrom,使我们可以访问cdrom中的数据,因为你将光盘插入cdrom中,Linux并不会自动挂载,必须使用Linux mount命 ...

  5. "Mon Dec 31 00:00:00 CST 2012" java日期装换 "yyyy-MM-dd"

    import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import ja ...

  6. PHP环境搭建-记录

    转于 http://jingyan.baidu.com/article/fcb5aff797ec41edaa4a71c4.html php5.5 做了大量的更新,在与apache搭配的时候如何选择也很 ...

  7. urllib,url中链接包含汉字怎么用百分号(%)加密处理

    使用urllib中的quote,和unquote方法将汉字编码成gbk(2个百分号对应一个汉字)或者utf8(3个百分号对应一个汉字) 注意用%加密汉字时,汉字不能是Unicode编码格式,否则会报错 ...

  8. Git的使用规范(一)

    1.建议使用 git add.2.不建议使用git commit -a3.撤销没有add的git checkout . 这个命令我们可以好好的介绍一下,如果当你对文件进行了修改,你没有进行git ad ...

  9. Java:static的作用分析

    static表示“静态”或者“全局”的意思,但在Java中不能在所有类之外定义全局变量,只能通过在一个类中定义公用.静态的变量来实现一个全局变量. 一.静态变量 1. Java中存在两种变量,一种是s ...

  10. Java RMI 入门指南

    开通博客也有好些天了,一直没有时间静下心来写博文,今天我就把两年前整理的一篇关于JAVA RMI入门级文章贴出来,供有这方面需要的同学们参考学习. RMI 相关知识 RMI全称是Remote Meth ...