【BZOJ4548】小奇的糖果
→原题传送门←(by Hzwer)
「题目背景」
小奇不小心让糖果散落到了地上,它对着满地的彩色糖果胡思乱想。
「问题描述」
有 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了,可以用树状数组来维护区间里的糖果数量。
- 然后想象一条扫描线,从下到上扫一遍,每一次把扫描线上的点屏蔽掉,再更新一次答案,这样就可以完成对于水平线上糖果的更新了。
- 那水平线下的怎么更新呢?一样的嘛,为了减少编程复杂度,我们把纵坐标取相反数,用一样的办法再做一次就可以了。
代码~
1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cstring> 5 #include<algorithm> 6 7 #define For(i,a,b) for(register int i=a;i<=b;++i) 8 #define Re register 9 #define Pn putchar('\n') 10 using namespace std; 11 const int N=1e5+10; 12 int Lc[N],Rc[N],lst[N]; 13 int X[N],sX[N]; 14 struct Point{ 15 int x,y,cl,id; 16 }pt[N]; 17 int c[N],n,m,x,y,Kx,ans=0; 18 19 inline void read(int &v){ 20 v=0; bool fg=0; 21 char c=getchar(); if(c=='-')fg=1; 22 while(c<'0'||c>'9'){c=getchar(); if(c=='-')fg=1;} 23 while(c>='0'&&c<='9'){v=v*10+c-'0',c=getchar(); if(c=='-')fg=1;} 24 if(fg)v=-v; 25 } 26 void write(int x){ 27 if(x>9)write(x/10); 28 int xx=x%10; 29 putchar(xx+'0'); 30 } 31 bool cmpX(const Point &a,const Point &b){ 32 return a.x<b.x; 33 } 34 bool cmpY(const Point &a,const Point &b){ 35 return a.y<b.y; 36 } 37 38 39 int LB(int x){ 40 return x&(-x); 41 } 42 void upD(int k,int dt){ 43 for(Re int i=k;i<=n;i+=LB(i)){ 44 c[i]+=dt; 45 } 46 } 47 int Qry(int k){ 48 int ans=0; 49 for(Re int i=k;i>=1;i-=LB(i)){ 50 ans+=c[i]; 51 } 52 return ans; 53 } 54 55 void makeA(int lx,int rx){ 56 if(lx>rx)return; 57 int tp=Qry(rx)-Qry(lx-1); 58 ans=max(tp,ans); 59 } 60 void PickupCandy(){ 61 62 X[0]=0; X[n+1]=n+1; 63 memset(lst,0,sizeof(lst)); 64 memset(c,0,sizeof(c)); 65 66 sort(pt+1,pt+n+1,cmpX); 67 68 For(i,1,n){ 69 upD(pt[i].x,1); 70 } 71 72 For(i,1,n){ 73 int ID=pt[i].id; 74 int prC=lst[pt[i].cl]; 75 Lc[ID]=prC; Rc[ID]=n+1; 76 if(prC) Rc[prC]=ID; 77 makeA(X[prC]+1,X[ID]-1); 78 lst[pt[i].cl]=ID; 79 } 80 For(i,1,Kx){ 81 makeA(X[lst[i]]+1,X[n+1]); 82 } 83 84 sort(pt+1,pt+n+1,cmpY); 85 86 int Px=1; 87 For(i,1,n){ 88 while(Px<=n&&pt[i].y==pt[Px].y){ 89 upD(X[pt[Px].id],-1); 90 Px++; 91 } 92 int ID=pt[i].id; 93 Lc[Rc[ID]]=Lc[ID]; Rc[Lc[ID]]=Rc[ID]; 94 makeA(X[Lc[ID]]+1,X[Rc[ID]]-1); 95 } 96 return; 97 } 98 99 int main(){ 100 //freopen("candy.in","r",stdin); 101 //freopen("candy.out","w",stdout); 102 int T; read(T); 103 while(T--){ 104 read(n); read(Kx); 105 ans=0; 106 For(i,1,n){ 107 read(pt[i].x); read(pt[i].y); read(pt[i].cl); 108 pt[i].id=i; 109 sX[i]=pt[i].x; 110 } 111 sort(sX+1,sX+n+1); 112 For(i,1,n){ 113 X[i]=lower_bound(sX+1,sX+n+1,pt[i].x)-sX; 114 pt[i].x=X[i]; 115 } 116 PickupCandy(); 117 For(i,1,n)pt[i].y*=-1; 118 PickupCandy(); 119 write(ans); Pn; 120 } 121 // fclose(stdin); fclose(stdout); 122 return 0; 123 }
转载于:https://www.cnblogs.com/HLAUV/p/9916248.html
【BZOJ4548】小奇的糖果相关推荐
- Bzoj 4548: 小奇的糖果(双向链表+排序+树状数组)
以下内容来自ShallWe's Blog 题目 4548: 小奇的糖果 Description 有\(N\)个彩色糖果在平面上.小奇想在平面上取一条水平的线段,并拾起它上方或下方的所有糖果.求出最多能 ...
- 【GDOI2018模拟7.14】小奇的糖果
Description 有 N 个彩色糖果在平面上.小奇想在平面上取一条水平的线段,并拾起它上方或下方的所有糖果.求出最多能够拾起多少糖果,使得获得的糖果并不包含所有的颜色. Input 包含多组测试 ...
- bzoj 4548: 小奇的糖果 bzoj 3658: Jabberwocky(双向链表+树状数组)
3658: Jabberwocky Time Limit: 20 Sec Memory Limit: 1024 MB Submit: 263 Solved: 107 [Submit][Status ...
- [乱搞 树状数组] BZOJ 4548 小奇的糖果 BZOJ 3658 Jabberwocky
跟悬线法有点像 #include<cstdio> #include<cstdlib> #include<algorithm> #include<cstring ...
- luogu P3817 小A的糖果
P3817 小A的糖果 题目描述 小A有N个糖果盒,第i个盒中有a[i]颗糖果. 小A每次可以从其中一盒糖果中吃掉一颗,他想知道,要让任意两个相邻的盒子中加起来都只有x颗或以下的糖果,至少得吃掉几颗糖 ...
- 小奇遐想 树状数组实现+容斥思想
问题 M: 小奇遐想 时间限制: 1 Sec 内存限制: 128 MB 提交: 165 解决: 21 [提交] [状态] [讨论版] [命题人:admin] 题目描述 撷来一缕清风飘渺 方知今日书 ...
- 【bzoj4550】小奇的博弈 博弈论+dp
题目描述 这个游戏是在一个1*n的棋盘上进行的,棋盘上有k个棋子,一半是黑色,一半是白色.最左边是白色棋子,最右边 是黑色棋子,相邻的棋子颜色不同. 小奇可以移动白色棋子,提比可以移动黑色的棋子,它们 ...
- bzoj 2281: [Sdoi2011]黑白棋 bzoj 4550: 小奇的博弈(Nimk博弈+DP)
4550: 小奇的博弈 Time Limit: 2 Sec Memory Limit: 256 MB Submit: 68 Solved: 42 [Submit][Status][Discuss] ...
- 状态规划P4270小奇挖矿2
问题描述 [题目背景] 小奇飞船的钻头开启了无限耐久+精准采集模式!这次它要将原矿运到泛光之源的矿石交易市场,以便为飞船升级无限非概率引擎. [问题描述] 现在有m+1个星球,从左到右标号为0到m,小 ...
最新文章
- Application provided invalid, non monotonically increasing dts to muxer in stream 0: -92233720368547
- linux定时备份mysql_linux定时备份MySQL数据库并删除七天前的备份文件
- 无法设置html过渡效果,html – CSS3过渡显示无阻止过度滚动
- 百度2015校园招聘软件开发笔试题及答案
- 天津知青网6周年网庆-京剧-智取威虎山片段
- 美观的导航菜单 -- JQuery实现,支持横向, 竖向
- myeclipse 编写html,myeclipse怎么写html
- android绘制矢量图_Android矢量可绘制
- 未能连接驱动人生服务器怎么解决,网卡驱动异常连不上网怎么办 驱动人生帮助你解决这个问题 - 驱动管家...
- 网络安全--通过握手包破解WiFi(详细教程)
- 懂生意的产品经理,才能做好商业化
- 身体健康是第一生产力 --- 我看央视主持人李咏早逝
- 为什么要进行前后端分离
- 什么是互联网产品经理
- java根据权重随机抽奖
- 判断图片是否为现场照片(Live Photo亦即内含Exif信息)
- eclipse 使用maven打包 包含非java文件时报错
- windows挂载webdav
- 删除feature的几种方法,性能
- 学习笔记(01):华为工程师,带你实战C++视频精讲-Day1王桂林老师原创视频-C到C++类型安全增强...