Bzoj4548 小奇的糖果(链表+树状数组)
题面
题解
很显然,我们只需要考虑单独取线段上方的情况,对于下方的把坐标取反再做一遍即可(因为我们只关心最终的答案)
建立树状数组维护一个横坐标区间内有多少个点,维护双向链表实现查询一个点左(右)横坐标最大(小)的与它相同的点。
首先枚举没有取到的颜色,找出所有不包含这种颜色的区间,更新答案。
接着考虑两个相同颜色的点的贡献,按照纵坐标从大到小枚举所有的点,分别在树状数组和双向链表中删除当前点,并利用这个点左右两边和它颜色相同的点之间的区间内点的个数更新答案。
#include <cstdio>
#include <cstring>
#include <algorithm>
using std::min; using std::max;
using std::sort; using std::swap;
using std::unique; using std::lower_bound;
typedef long long ll;
template<typename T>
void read(T &x) {
int flag = 1; x = 0; char ch = getchar();
while(ch < '0' || ch > '9') { if(ch == '-') flag = -flag; ch = getchar(); }
while(ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar(); x *= flag;
}
const int N = 1e5 + 10;
int T, n, K, x[N], ans;
struct data { int x, y, z, id; } p[N];
int disc[N], t[N];//树状数组
int last[N], l[N], r[N];//双向链表
void add (int x, int y) { while(x <= n + 1) t[x] += y, x += (x & -x); }
int query (int x) { int y = 0; while(x) y += t[x], x -= (x & -x); return y; }
inline bool cmpx(const data &a, const data &b) { return a.x < b.x; }
inline bool cmpy(const data &a, const data &b) { return a.y < b.y; }
void update(int l, int r) {
if(l > r) return ;
int tmp = query(r) - query(l - 1);
ans = max(tmp, ans);
}
void doit () {
x[0] = 0, x[n + 1] = n + 1;
memset(last, 0, sizeof last), memset(t, 0, sizeof t);
sort(&p[1], &p[n + 1], cmpx);
for(int i = 1; i <= n; ++i) add(p[i].x, 1);
for(int i = 1; i <= n; ++i) {
int t = p[i].id, L= last[p[i].z];
l[t] = L, r[t] = n + 1;
if(L) r[L] = t;
update(x[L] + 1, x[t] - 1);
last[p[i].z] = t;
}
for(int i = 1; i <= K; ++i)
update(x[last[i]] + 1, n + 1);
sort(&p[1], &p[n + 1], cmpy);
for(int i = 1, j = 1; i <= n; ++i) {
int t = p[i].id;
while(j <= n && p[j].y == p[i].y) add(p[j].x, - 1), ++j;
l[r[t]] = l[t], r[l[t]] = r[t];
update(x[l[t]] + 1, x[r[t]] - 1);
}
}
int main () {
read(T);
while(T--) {
ans = 0, read(n), read(K); int m = n;
for(int i = 1; i <= n; ++i)
read(p[i].x), read(p[i].y), read(p[i].z), p[i].id = i;
for(int i = 1; i <= n; ++i)
disc[i] = p[i].x;
sort(&disc[1], &disc[m + 1]), m = unique(&disc[1], &disc[m + 1]) - disc - 1;
for(int i = 1; i <= n; ++i) {
p[i].x = lower_bound(&disc[1], &disc[m + 1], p[i].x) - disc;
x[i] = p[i].x;
}
doit(); for(int i = 1; i <= n; ++i) p[i].y = -p[i].y; doit();
printf("%d\n", ans);
}
return 0;
}
Bzoj4548 小奇的糖果(链表+树状数组)的更多相关文章
- 【bzoj4548】小奇的糖果 STL-set+树状数组
题目描述 平面上有n个点,每个点有一种颜色.对于某一条线段,选择所有其上方或下方的点.求:在不包含所有颜色的点的前提下,选择的点数最多是多少.(本题中如果存在某颜色没有相应的点,那么选择任何线段都不算 ...
- 【题解】BZOJ4548 小奇的糖果(树状数组)
[题解]BZOJ4548 小奇的糖果(树状数组) 说在前面:我有个同学叫小奇,他有一个朋友叫达达,达达特爱地理和旅游,初中经常AK地理,好怀恋和他已经达达一起到当时初中附近许多楼盘的顶楼逛的时光... ...
- 【BZOJ4548】小奇的糖果 set(链表)+树状数组
[BZOJ4548]小奇的糖果 Description 有 N 个彩色糖果在平面上.小奇想在平面上取一条水平的线段,并拾起它上方或下方的所有糖果.求出最多能够拾起多少糖果,使得获得的糖果并不包含所有的 ...
- BZOJ4548 小奇的糖果
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000作者博客:http://www.cnblogs.com/ljh2000-jump/转 ...
- 【题解】 BZOJ4548 小奇的糖果
本文同步在学弟ZCDHJ的个人博客发布,审核需要一段时间. 传送门 考虑题目中获得的糖果并不包含所有的颜色这句话,发现相当于我们可以直接选取某一个颜色强制不能选(这样子一定最优). 然后就可以考虑分开 ...
- 【BZOJ3295】【块状链表+树状数组】动态逆序对
Description 对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对(i,j)的个数.给1到n的一个排列,按照某种顺序依次删除m个元素,你的任务是在每次删除一个元素之前统计 ...
- HH的项链题解(离线思想+链表+树状数组)
本人第一篇博客重磅推出!!! 希望各位朋友以后多多捧场也多给写意见(我个人喜欢把题解写得啰嗦一点,因为这样方便理解,各位巨佬勿喷) 来讲一道提高+/省选-的骚题:HH的项链(这个HH你理解成皇后呵呵哈 ...
- 【Luogu】P1972HH的项链(链表+树状数组)
题目链接 难题,所以会讲得细一些. 首先我们想如何统计区间[l,r]内不同贝壳的个数. 第一个思路就是线段树/树状数组,query(1,r)-query(1,l-1)对不对? 然而这样是不对的. 然后 ...
- 算法笔记求序列A每个元素左边比它小的数的个数(树状数组和离散化)
#include <iostream> #include <algorithm> #include <cstring> using namespace std ; ...
随机推荐
- HDU 1994 利息计算 数学题
解题报告:算利息的,不过一开始格式控制符里面少写了一个%lf,一直没看到,愣是没找到错误,唉! #include<cstdio> int main() { int T; scanf(&qu ...
- UVA1386 【Cellular Automaton】题解
题面:UVA1386 Cellular Automaton 矩阵乘法+快速幂解法: 这是一个比较裸的有点复杂需要优化的矩乘快速幂,所以推荐大家先做一下下列洛谷题目练练手: (会了,差不多就是多倍经验题 ...
- python概念-常用模块之究竟你是什么鬼
模块: 一个模块就是一个包含了python定义和声明的文件,文件名就是模块名字加上.py的后缀. 说白了,就是一个python文件中定义好了类和方法,实现了一些功能,可以被别的python文件所调用 ...
- erp前端项目总结
目录 一.项目目录(vue-cli2) 二.开发实践 (一) 权限 (二) 各组件间传递数据 (四) 路由 (七) 组织部门业务员三级联动 (八) 优化性能,手动绑定下拉框数据 (九) 验证 (十) ...
- php实现异步请求
PHP开启异步多线程执行脚本 装载自:http://www.cnblogs.com/clphp/p/4913214.html 场景要求 客户端调用服务器a.php接口,需要执行一个长达5s-20s不 ...
- 判断最小生成树是否为一(krustra)
题目链接:https://vjudge.net/contest/66965#problem/K 具体思路: 首先跑一遍最短路算法,然后将使用到的边标记一下,同时使用一个数组记录每一个权值出现的次数,如 ...
- ubuntu 14.04安装JDK
As a workaround, you can install OpenJDK 8 from a PPA repository: 1. Open terminal from the Dash or ...
- Shell脚本中字符串判空:使用-z 字符串长度为0时,为真,-n字符串长度不为0,为真。这两个都不靠谱【转】
最近发现使用 -z 和 -n 来判断字符串判空,或不空时,很不靠谱. 使用下面的方法最可靠: if [ "x${value}" == "x" ] ...
- Python_oldboy_自动化运维之路_全栈考试(七)
1. 计算100-300之间所有能被3和7整除的所有数之和 # -*- coding: UTF-8 -*- #blog:http://www.cnblogs.com/linux-chenyang/ c ...
- python面向对象(五)之多态
继承 在讲多态之前我们再复习下继承,下面是一个例子. Circle 和 Rectangle 继承自 Shape,不同的图形,面积(area)计算方式不同. # shape.py class S ...