【BZOJ4548】小奇的糖果
「题目背景」
小奇不小心让糖果散落到了地上,它对着满地的彩色糖果胡思乱想。
「问题描述」
有 N 个彩色糖果在平面上。小奇想在平面上取一条水平的线段,并拾起它上方或下方的所有糖果。求出最多能够拾起多少糖果,使得获得的糖果并不包含所有的颜色。
「输入格式」
包含多组测试数据,第一行输入一个正整数 T 表示测试数据组数。
接下来 T 组测试数据,对于每组测试数据,第一行输入两个正整数 N、K,分别表示点数和颜色数。
接下来 N 行,每行描述一个点,前两个数 x, y (|x|, |y| ≤ 2^30 – 1) 描述点的位置,最后一个数 z (1 ≤ z ≤ k) 描述点的颜色。
「输出格式」
对于每组数据在一行内输出一个非负整数 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
「数据范围」
对于 30% 的数据,N ≤ 100;
对于 60% 的数据,N ≤ 5000;
对于 100% 的数据,N ≤ 100000,K ≤ 100000,T ≤ 3。

第N道小奇系列的题目了(之前好像也做过一道小奇的糖果来着,不过那是IOI改编,有点难)
模拟考的时候写了暴力居然没有分(!)
下面是自己写的题解:
- 这是在糖果是撒在二维平面里的,所以我们可以通过其中一维的坐标离散化,然后通过枚举,转成单一一维里的问题。
- 把横坐标离散化掉,按横坐标从左到右,把横坐标相邻的糖果用双向的链表串在一起(对于有不同颜色的序列,这样的操作很常见哦,记下来记下来)。
- 所以每一次在两个相同颜色的糖果之间数一下其它糖果的数量,就可以来更新ans了,可以用树状数组来维护区间里的糖果数量。
- 然后想象一条扫描线,从下到上扫一遍,每一次把扫描线上的点屏蔽掉,再更新一次答案,这样就可以完成对于水平线上糖果的更新了。
- 那水平线下的怎么更新呢?一样的嘛,为了减少编程复杂度,我们把纵坐标取相反数,用一样的办法再做一次就可以了。
代码~
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm> #define For(i,a,b) for(register int i=a;i<=b;++i)
#define Re register
#define Pn putchar('\n')
using namespace std;
const int N=1e5+;
int Lc[N],Rc[N],lst[N];
int X[N],sX[N];
struct Point{
int x,y,cl,id;
}pt[N];
int c[N],n,m,x,y,Kx,ans=; inline void read(int &v){
v=; bool fg=;
char c=getchar(); if(c=='-')fg=;
while(c<''||c>''){c=getchar(); if(c=='-')fg=;}
while(c>=''&&c<=''){v=v*+c-'',c=getchar(); if(c=='-')fg=;}
if(fg)v=-v;
}
void write(int x){
if(x>)write(x/);
int xx=x%;
putchar(xx+'');
}
bool cmpX(const Point &a,const Point &b){
return a.x<b.x;
}
bool cmpY(const Point &a,const Point &b){
return a.y<b.y;
} int LB(int x){
return x&(-x);
}
void upD(int k,int dt){
for(Re int i=k;i<=n;i+=LB(i)){
c[i]+=dt;
}
}
int Qry(int k){
int ans=;
for(Re int i=k;i>=;i-=LB(i)){
ans+=c[i];
}
return ans;
} void makeA(int lx,int rx){
if(lx>rx)return;
int tp=Qry(rx)-Qry(lx-);
ans=max(tp,ans);
}
void PickupCandy(){ X[]=; X[n+]=n+;
memset(lst,,sizeof(lst));
memset(c,,sizeof(c)); sort(pt+,pt+n+,cmpX); For(i,,n){
upD(pt[i].x,);
} For(i,,n){
int ID=pt[i].id;
int prC=lst[pt[i].cl];
Lc[ID]=prC; Rc[ID]=n+;
if(prC) Rc[prC]=ID;
makeA(X[prC]+,X[ID]-);
lst[pt[i].cl]=ID;
}
For(i,,Kx){
makeA(X[lst[i]]+,X[n+]);
} sort(pt+,pt+n+,cmpY); int Px=;
For(i,,n){
while(Px<=n&&pt[i].y==pt[Px].y){
upD(X[pt[Px].id],-);
Px++;
}
int ID=pt[i].id;
Lc[Rc[ID]]=Lc[ID]; Rc[Lc[ID]]=Rc[ID];
makeA(X[Lc[ID]]+,X[Rc[ID]]-);
}
return;
} int main(){
//freopen("candy.in","r",stdin);
//freopen("candy.out","w",stdout);
int T; read(T);
while(T--){
read(n); read(Kx);
ans=;
For(i,,n){
read(pt[i].x); read(pt[i].y); read(pt[i].cl);
pt[i].id=i;
sX[i]=pt[i].x;
}
sort(sX+,sX+n+);
For(i,,n){
X[i]=lower_bound(sX+,sX+n+,pt[i].x)-sX;
pt[i].x=X[i];
}
PickupCandy();
For(i,,n)pt[i].y*=-;
PickupCandy();
write(ans); Pn;
}
// fclose(stdin); fclose(stdout);
return ;
}
【BZOJ4548】小奇的糖果的更多相关文章
- 【题解】BZOJ4548 小奇的糖果(树状数组)
[题解]BZOJ4548 小奇的糖果(树状数组) 说在前面:我有个同学叫小奇,他有一个朋友叫达达,达达特爱地理和旅游,初中经常AK地理,好怀恋和他已经达达一起到当时初中附近许多楼盘的顶楼逛的时光... ...
- BZOJ4548 小奇的糖果
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000作者博客:http://www.cnblogs.com/ljh2000-jump/转 ...
- Bzoj4548 小奇的糖果(链表+树状数组)
题面 Bzoj 题解 很显然,我们只需要考虑单独取线段上方的情况,对于下方的把坐标取反再做一遍即可(因为我们只关心最终的答案) 建立树状数组维护一个横坐标区间内有多少个点,维护双向链表实现查询一个点左 ...
- 【题解】 BZOJ4548 小奇的糖果
本文同步在学弟ZCDHJ的个人博客发布,审核需要一段时间. 传送门 考虑题目中获得的糖果并不包含所有的颜色这句话,发现相当于我们可以直接选取某一个颜色强制不能选(这样子一定最优). 然后就可以考虑分开 ...
- bzoj4548: 小奇的糖果 题解
题目链接 题解 不包含所有颜色 就强制不选一个颜色 图中圆点颜色相同 矩形越大,包括的点一定不比其一小部分少 如图所示,最大矩形只有3种 离散化\(x\)坐标 然后按\(y\)排序 每次取出颜色的前驱 ...
- 【BZOJ4548】小奇的糖果 set(链表)+树状数组
[BZOJ4548]小奇的糖果 Description 有 N 个彩色糖果在平面上.小奇想在平面上取一条水平的线段,并拾起它上方或下方的所有糖果.求出最多能够拾起多少糖果,使得获得的糖果并不包含所有的 ...
- 【BZOJ-4548&3658】小奇的糖果&Jabberwocky 双向链表 + 树状数组
4548: 小奇的糖果 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 103 Solved: 47[Submit][Status][Discuss] ...
- 小奇的糖果(candy)
[题目背景]小奇不小心让糖果散落到了地上,它对着满地的彩色糖果胡思乱想.[问题描述]有 N 个彩色糖果在平面上. 小奇想在平面上取一条水平的线段,并拾起它上方或下方的所有糖果.求出最多能够拾起多少糖果 ...
- 【bzoj4548】小奇的糖果 STL-set+树状数组
题目描述 平面上有n个点,每个点有一种颜色.对于某一条线段,选择所有其上方或下方的点.求:在不包含所有颜色的点的前提下,选择的点数最多是多少.(本题中如果存在某颜色没有相应的点,那么选择任何线段都不算 ...
随机推荐
- 学习selendroid初衷
为了解决工作中的一个问题,开始学习selendroid. 工作中,有一些所谓H5应用需要测试,这些应用程序描述如下: 通过微信平台传播,也就是依靠微信的朋友圈传播: 可以通过类似于http://XXX ...
- 调用远程service aidl接口定义
Android studio 查看aidl定义的文件:当你进入你的AIDL文件并编写好了之后,点击AS上方菜单栏中的Build->Make Project,之后便可以在当前工程的app/buil ...
- 基于BASYS2的VHDL程序——数字钟
在编电子表时发现FPGA求余,取模只能针对2的次方.毕竟是数字的嘛! 时钟用到了动态刷新数码管.以一个大于50Hz的速度刷新每一个数码管. 因为数码管只有四个,只写了分针和秒针. 代码如下: libr ...
- 记录 Linux分析apache日志获取最多访问的前10个IP
摘自: http://blog.csdn.net/tanga842428/article/details/52856413
- httpd 隐藏文件
问题情况, 因磁盘空间问题,使用rsync将 php工作目录下文件copy到新盘中后,出现 php服务很多目录访问返回 404,路径找不到,其实文件都存在,而且路径都是对的 解决思路. 根目录下 有个 ...
- 关于Javascript中声明变量、函数的笔记
一.概念 1.变量声明 在JavaScript中,变量一般通过var关键字(隐式声明,let关键字声明除外)进行声明,如下通过var关键字声明a,b,c三个变量(并给其中的a赋值): var a=1, ...
- codeforces A. Point on Spiral 解题报告
题目链接:http://codeforces.com/problemset/problem/279/A 题目意思:给出一个坐标点(x, y),问当从(0, 0) 开始到达该点转过的拐角有多少个.(拐角 ...
- 基于aspectj实现AOP操作的两种方式——xml配置
1. 要导入的 jar 包: 常用的aspectj表达式: 权限修饰符可以省略,以下表示:返回值类型为任意,com.chy.service包以及其子包下的.任意类的.参数任意的.任意方法 execut ...
- Watir RAutomation VS AutoIt to deal with popup
Watir使用过程中,经常遇到的弹出框分为几类: 1. Alert 2. Confirm 3. Prompt 4. File select Watir 处理弹出框,有很多方法,可以应用 AutoIt来 ...
- 条件变量pthread_cond_wait()和pthread_cond_signal()详解
条件变量 条件变量是利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作:一个线程等待"条件变量的条件成立"而挂起:另一个线程使"条件成立" ...