【GDOI2018模拟7.14】小奇的糖果 树状数组+扫描线
来源:互联网 发布:适合学生的网络兼职 编辑:程序博客网 时间:2024/05/09 19:04
好像上去讲的有点快,主要是本身就挺短,,这里讲的会详细一点。
题意很明显就不说了。
题意就不说了,注意线段上的点是不能选的。
首先要明确一个东西,这里说是双向链表维护,是因为我们维护了一个点的前驱后继,这符合双向链表的定义,但是实际上大家把他当作普通数组一样维护就好了。
先把横坐标离散化,注意是线性离散的话初值不能是0因为有的坐标可以是0(因为这个所以WA0了)。
首先我们假设我们画的那一条直线在无限低的地方,这时候答案相当于相邻两个同种颜色的中间的最大点数。(注意不包括这种颜色)
怎么求?
把横坐标从小到大排序,维护l[i],r[i]分别表示距离i最近的相同颜色的点的编号。
直接维护比较麻烦,设一个last[i]表示i这种颜色最近一次出现的地方在哪个位置,然后用last维护l,r。
维护的同时维护答案,用树状数组和l,r维护一下区间和就好了。
当然,这是满状态,也就是直线在最下方的时候,然后我们将点按照纵坐标排序,逐渐向上移动,每一次将同一行的点从树状数组删掉,然后将l,r合并。同时维护答案,跟上面的一样,用已经合并了的l,r更新一下就好了。
最后还有一种情况就是枚举一下哪一种颜色不选,然后对ans取个max,注意要在删点之前,也是用树状数组维护。
#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>#define fo(i,a,b) for(int i=a;i<=b;i++)#define fd(i,a,b) for(int i=a;i>=b;i--)using namespace std;const int N=1e5+5;int n,k,ans;struct point{ int x,y,id,col;}po[N];int a[N],pos[N],val[N],last[N],Left[N],Right[N];//int f[2][N][N];inline int lowbit(int x){ return x&(-x);}inline void add(int x,int v){ while (x<=n+1) { val[x]+=v; x+=lowbit(x); }}inline int ask(int x){ int ret=0; while (x>0) { ret+=val[x]; x-=lowbit(x); } return ret;}bool cmp1(point a,point b){ return a.x<b.x;}bool cmp2(point a,point b){ return a.y<b.y;}inline void solve(){ memset(val,0,sizeof(val)); memset(last,0,sizeof(last)); sort(po+1,po+1+n,cmp1); pos[n+1]=n+1; fo(i,1,n)add(po[i].x,1); fo(i,1,n) { int l=last[po[i].col]; Left[po[i].id]=l,Right[po[i].id]=n+1; last[po[i].col]=po[i].id; if (l)Right[l]=po[i].id; if (pos[l]+1<=pos[po[i].id]-1)ans=max(ans,ask(pos[po[i].id]-1)-ask(pos[l])); } fo(i,1,k)if (pos[last[i]]+1<=n)ans=max(ans,ask(n+1)-ask(pos[last[i]])); sort(po+1,po+1+n,cmp2); int j=1; fo(i,1,n) { while (j<=n&&po[i].y==po[j].y)add(po[j].x,-1),j++; Left[Right[po[i].id]]=Left[po[i].id]; Right[Left[po[i].id]]=Right[po[i].id]; if (pos[Right[po[i].id]]-1>=pos[Left[po[i].id]]+1) ans=max(ans,ask(pos[Right[po[i].id]]-1)-ask(pos[Left[po[i].id]])); }}int main(){ int cas=0; scanf("%d",&cas); while (cas--) { scanf("%d%d",&n,&k); fo(i,1,n) { scanf("%d%d%d",&po[i].x,&po[i].y,&po[i].col); a[i]=po[i].x; po[i].id=i; //fo(j,1,n) //f[0][i][j]=abs(po[i].x-po[j].x),f[1][i][j]=abs(po[i].y-po[j].y); } sort(a+1,a+1+n); int tot=0; ans=0; fo(i,1,n) po[i].x=pos[i]=lower_bound(a+1,a+1+n,po[i].x)-a; solve(); fo(i,1,n)po[i].y=-po[i].y; solve(); printf("%d\n",ans); }}
阅读全文
0 0
- 【GDOI2018模拟7.14】小奇的糖果 树状数组+扫描线
- 【GDOI2018模拟7.14】小奇的糖果
- 【JZOJ5229】【GDOI2018模拟7.14】小奇的糖果
- [bzoj4548]【GDOI2018模拟7.14】小奇的糖果
- 【JZOJ 5229】【GDOI2018模拟7.14】小奇的糖果
- 【jozj5228】【GDOI2018模拟7.14】【小奇的集合】【矩阵乘法】
- JZOJ5228. 【GDOI2018模拟7.14】小奇的集合
- [乱搞 树状数组] BZOJ 4548 小奇的糖果 && BZOJ 3658 Jabberwocky
- bzoj 4548: 小奇的糖果(线段树+树状数组)
- bzoj 4548: 小奇的糖果 双向链表+树状数组
- bzoj 4548: 小奇的糖果 && bzoj 3658: Jabberwocky(双向链表+树状数组)
- 【BZOJ4548】小奇的糖果
- BZOJ4548 小奇的糖果
- [JZOJ5229] 小奇的糖果
- 【BZOJ4548】小奇的糖果
- 【GDOI2018模拟7.12】A 线段树+树状数组
- BZOJ 4548 小奇的糖果
- 【bzoj 4548】【JZOJ 5229】 小奇的糖果
- 嵌入式每日学习心得2017.07.14
- React-Native 命令备忘
- JZOJ 100047. 【NOIP2017提高A组模拟7.14】基因变异
- Java多线程____Executors线程池的使用和架构原理
- Pinhole camera model相机模型
- 【GDOI2018模拟7.14】小奇的糖果 树状数组+扫描线
- 关于请求能抓包到数据但是request取不到数据的问题
- Dagger2在Android开发中的应用
- win32汇编-使用子程序以及堆栈平衡原理
- 使用plsq实现文件压缩zip
- html+css实现子div在父div中居中
- 测试道路之第二周
- Cannot load driver class: com.mysql.jdbc.Driver
- Hive QL详解