题面

Bzoj

题解

很显然,我们只需要考虑单独取线段上方的情况,对于下方的把坐标取反再做一遍即可(因为我们只关心最终的答案)

建立树状数组维护一个横坐标区间内有多少个点,维护双向链表实现查询一个点左(右)横坐标最大(小)的与它相同的点。

首先枚举没有取到的颜色,找出所有不包含这种颜色的区间,更新答案。

接着考虑两个相同颜色的点的贡献,按照纵坐标从大到小枚举所有的点,分别在树状数组和双向链表中删除当前点,并利用这个点左右两边和它颜色相同的点之间的区间内点的个数更新答案。

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <algorithm>
  4. using std::min; using std::max;
  5. using std::sort; using std::swap;
  6. using std::unique; using std::lower_bound;
  7. typedef long long ll;
  8. template<typename T>
  9. void read(T &x) {
  10. int flag = 1; x = 0; char ch = getchar();
  11. while(ch < '0' || ch > '9') { if(ch == '-') flag = -flag; ch = getchar(); }
  12. while(ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar(); x *= flag;
  13. }
  14. const int N = 1e5 + 10;
  15. int T, n, K, x[N], ans;
  16. struct data { int x, y, z, id; } p[N];
  17. int disc[N], t[N];//树状数组
  18. int last[N], l[N], r[N];//双向链表
  19. void add (int x, int y) { while(x <= n + 1) t[x] += y, x += (x & -x); }
  20. int query (int x) { int y = 0; while(x) y += t[x], x -= (x & -x); return y; }
  21. inline bool cmpx(const data &a, const data &b) { return a.x < b.x; }
  22. inline bool cmpy(const data &a, const data &b) { return a.y < b.y; }
  23. void update(int l, int r) {
  24. if(l > r) return ;
  25. int tmp = query(r) - query(l - 1);
  26. ans = max(tmp, ans);
  27. }
  28. void doit () {
  29. x[0] = 0, x[n + 1] = n + 1;
  30. memset(last, 0, sizeof last), memset(t, 0, sizeof t);
  31. sort(&p[1], &p[n + 1], cmpx);
  32. for(int i = 1; i <= n; ++i) add(p[i].x, 1);
  33. for(int i = 1; i <= n; ++i) {
  34. int t = p[i].id, L= last[p[i].z];
  35. l[t] = L, r[t] = n + 1;
  36. if(L) r[L] = t;
  37. update(x[L] + 1, x[t] - 1);
  38. last[p[i].z] = t;
  39. }
  40. for(int i = 1; i <= K; ++i)
  41. update(x[last[i]] + 1, n + 1);
  42. sort(&p[1], &p[n + 1], cmpy);
  43. for(int i = 1, j = 1; i <= n; ++i) {
  44. int t = p[i].id;
  45. while(j <= n && p[j].y == p[i].y) add(p[j].x, - 1), ++j;
  46. l[r[t]] = l[t], r[l[t]] = r[t];
  47. update(x[l[t]] + 1, x[r[t]] - 1);
  48. }
  49. }
  50. int main () {
  51. read(T);
  52. while(T--) {
  53. ans = 0, read(n), read(K); int m = n;
  54. for(int i = 1; i <= n; ++i)
  55. read(p[i].x), read(p[i].y), read(p[i].z), p[i].id = i;
  56. for(int i = 1; i <= n; ++i)
  57. disc[i] = p[i].x;
  58. sort(&disc[1], &disc[m + 1]), m = unique(&disc[1], &disc[m + 1]) - disc - 1;
  59. for(int i = 1; i <= n; ++i) {
  60. p[i].x = lower_bound(&disc[1], &disc[m + 1], p[i].x) - disc;
  61. x[i] = p[i].x;
  62. }
  63. doit(); for(int i = 1; i <= n; ++i) p[i].y = -p[i].y; doit();
  64. printf("%d\n", ans);
  65. }
  66. return 0;
  67. }

Bzoj4548 小奇的糖果(链表+树状数组)的更多相关文章

  1. 【bzoj4548】小奇的糖果 STL-set+树状数组

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

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

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

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

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

  4. BZOJ4548 小奇的糖果

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

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

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

  6. 【BZOJ3295】【块状链表+树状数组】动态逆序对

    Description 对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对(i,j)的个数.给1到n的一个排列,按照某种顺序依次删除m个元素,你的任务是在每次删除一个元素之前统计 ...

  7. HH的项链题解(离线思想+链表+树状数组)

    本人第一篇博客重磅推出!!! 希望各位朋友以后多多捧场也多给写意见(我个人喜欢把题解写得啰嗦一点,因为这样方便理解,各位巨佬勿喷) 来讲一道提高+/省选-的骚题:HH的项链(这个HH你理解成皇后呵呵哈 ...

  8. 【Luogu】P1972HH的项链(链表+树状数组)

    题目链接 难题,所以会讲得细一些. 首先我们想如何统计区间[l,r]内不同贝壳的个数. 第一个思路就是线段树/树状数组,query(1,r)-query(1,l-1)对不对? 然而这样是不对的. 然后 ...

  9. 算法笔记求序列A每个元素左边比它小的数的个数(树状数组和离散化)

    #include <iostream> #include <algorithm> #include <cstring> using namespace std ; ...

随机推荐

  1. 腾讯高级设计师谈微信的旧容与新妆,Android Design是大势所趋

    编者按:本篇投稿选自腾讯大讲堂(更多腾讯产品技术文章,可以关注“腾讯大讲堂”微信公众账号),由腾讯研发管理部高级设计师Vertu撰写,他以产品设计师的视角,对比解读了微信的旧容与新妆,也讲了Andro ...

  2. xpack文件打包解包代码库

    Github ###概述 xpack是一个文件资源打包工具及类库,可以对多文件进行打包解包. 其使用文件名的hash作为索引,建立hash索引表以加速文件查找. ###特性 支持hashid自动解冲突 ...

  3. 20155213 2016-2017-2 《Java程序设计》第五周学习总结

    20155213 2016-2017-2 <Java程序设计>第五周学习总结 教材学习内容总结 Java中所有错误都会被打包为对象,运用try.catch,可以在错误发生时显示友好的错误信 ...

  4. Python练习-time模块

    明天的明天的明天,雾草! # 编辑者:闫龙 #显示当前时间三天后是星期几? import time t = time.time()+((24*3600)*3) tl = time.localtime( ...

  5. php Only variables should be passed by reference 报错问题

    这个错误是变量引用引起的非致命错误,可修改php.ini文件的error_reporting = E_ALL & E_NOTICE 使其屏蔽此错误

  6. redis安装(linux)

    一.redis安装步骤 1.yum install gcc  如果你机器已经安装了编译环境请忽略,否则在使用make编译源码时会报错. 报错信息:make: *** [adlist.o]  2.使用w ...

  7. 【Andorid开发框架学习】之Volley入门

    Volley是Android平台上的网络通信库,能使网络通信更快,更简单,更健壮.Volley特别适合数据量不大但是通信频繁的场景.在listView显示图片这方面,使用volley也是比较好的,不必 ...

  8. Windows 10安装uWSGI:不可行、失败了

    Windows 10家庭中文版,Python 3.6.4,uwsgi-2.0.17.tar.gz,压缩工具-7-zip 提示:请不要和我一样尝试,浪费时间,去Linux上玩吧! 几个小时的安装经历 昨 ...

  9. Python访问MySQL(1):初步使用PyMySQL包

    Windows 10家庭中文版,MySQL 5.7.20 for Win 64,Python 3.6.4,PyMySQL 0.8.1,2018-05-08 ---- 使用Python访问MySQL数据 ...

  10. 洛谷P2746校园网

    传送门啦 下面来看任务B.我们发现,图中只要存在入度为0的点和出度为0的点就永远不可能满足要求:" 不论我们给哪个学校发送新软件,它都会到达其余所有的学校 ".我们还发现,只要在入 ...