考虑将某线段下方的点取走:

将所有点从低到高排序

每扫描到一条水平线,对于上面每个点,找到它下面同色的前驱后继,统计中间点的个数

然后再把线上所有点插入数据结构中

最后再统计相邻的同色的点之间的点个数

用动态开点的权值线段树+树状数组维护,时间复杂度$O(n\log n)$。

考虑将某线段上方的点取走:

把扫描线的顺序反过来即可

注意特判出现颜色数没达到k的情况。

#include<cstdio>
#include<algorithm>
using namespace std;
const int N=100010,M=1800000;
int C,n,k,i,j,ans,bit[N],b[N],vis[N];
struct P{int x,y,c;}a[N];
inline bool cmpc(P a,P b){return a.c==b.c?a.x<b.x:a.c<b.c;}
inline bool cmpy(P a,P b){return a.y<b.y;}
inline void up(int x){if(ans<x)ans=x;}
inline int lower(int x){
int l=1,r=n,t,mid;
while(l<=r)if(b[mid=(l+r)>>1]<=x)l=(t=mid)+1;else r=mid-1;
return t;
}
inline void add(int x){for(;x<=n;x+=x&-x)bit[x]++;}
inline int ask(int x){int t=0;for(;x;x-=x&-x)t+=bit[x];return t;}
inline void read(int&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';}
int T[N],vl[M],vr[M],l[M],r[M],tot,pre,nxt;
void ins(int&x,int a,int b,int c){
if(!x)x=++tot;
if(a==b){vl[x]=vr[x]=a;return;}
int mid=(a+b)>>1;
if(c<=mid)ins(l[x],a,mid,c);else ins(r[x],mid+1,b,c);
vl[x]=vl[l[x]]?vl[l[x]]:vl[r[x]];
vr[x]=vr[r[x]]?vr[r[x]]:vr[l[x]];
}
void getl(int x,int a,int b,int c){
if(!x||nxt)return;
if(c<=a){nxt=vl[x];return;}
int mid=(a+b)>>1;
if(c<=mid)getl(l[x],a,mid,c);
getl(r[x],mid+1,b,c);
}
void getr(int x,int a,int b,int d){
if(!x||pre)return;
if(b<=d){pre=vr[x];return;}
int mid=(a+b)>>1;
if(d>mid)getr(r[x],mid+1,b,d);
getr(l[x],a,mid,d);
}
int main(){
for(read(C);C--;printf("%d\n",ans)){
read(n),read(k);
for(i=1;i<=k;i++)vis[i]=0;
for(ans=0,i=1;i<=n;i++)read(a[i].x),read(a[i].y),read(a[i].c),b[i]=a[i].x,vis[a[i].c]=1;
for(sort(b+1,b+n+1),sort(a+1,a+n+1,cmpy),i=1;i<=n;i++)a[i].x=lower(a[i].x);
for(i=1;i<=n;i++)bit[i]=0;
for(i=1;i<=k;i++)if(!vis[i]){ans=n;break;}
if(ans)continue;
for(i=1;i<=tot;i++)vl[i]=vr[i]=l[i]=r[i]=0;tot=0;
for(i=1;i<=k;i++)T[i]=0,ins(T[i],0,n+1,0),ins(T[i],0,n+1,n+1);
for(i=1;i<=n;i=j){
for(j=i;j<=n&&a[j].y==a[i].y;j++){
pre=nxt=0,getl(T[a[j].c],0,n+1,a[j].x),getr(T[a[j].c],0,n+1,a[j].x);
up(ask(nxt-1)-ask(pre));
}
for(j=i;j<=n&&a[j].y==a[i].y;j++)ins(T[a[j].c],0,n+1,a[j].x),add(a[j].x);
}
for(i=1;i<=n;i++)bit[i]=0;
for(i=1;i<=tot;i++)vl[i]=vr[i]=l[i]=r[i]=0;tot=0;
for(i=1;i<=k;i++)T[i]=0,ins(T[i],0,n+1,0),ins(T[i],0,n+1,n+1);
for(i=n;i;i=j){
for(j=i;j&&a[j].y==a[i].y;j--){
pre=nxt=0,getl(T[a[j].c],0,n+1,a[j].x),getr(T[a[j].c],0,n+1,a[j].x);
up(ask(nxt-1)-ask(pre));
}
for(j=i;j&&a[j].y==a[i].y;j--)ins(T[a[j].c],0,n+1,a[j].x),add(a[j].x);
}
for(sort(a+1,a+n+1,cmpc),i=1;i<=n;i++)bit[i]=0;
for(i=1;i<=n;i++)bit[a[i].x]++;
for(i=2;i<=n;i++)bit[i]+=bit[i-1];
for(i=1;i<n;i++)if(a[i].c==a[i+1].c)up(bit[a[i+1].x-1]-bit[a[i].x]);
else up(max(n-bit[a[i].x],bit[a[i+1].x-1]));
up(max(bit[a[1].x-1],n-bit[a[n].x]));
}
return 0;
}

  

最新文章

  1. HIS系统的处方录入控件
  2. XHTML学习进度备忘
  3. jQuery 自定义事件的学习笔记
  4. 缩小jquery体积
  5. iOS自定义的UISwitch按钮
  6. oracle登陆连接的问题
  7. Adobe/Flash Media Server 5.0 linux 64位系统下的安装
  8. POJ 2752 Seek the Name, Seek the Fame(求所有既是前缀又是后缀的子串长度)
  9. QT显示机制(7篇相关文章)
  10. Android 儿子Activity在启动过程中的流程组件 &amp;amp;&amp;amp; 儿子Activity在一个新的进程组件启动过程
  11. angular2 日期格式化
  12. Log4net日志记录、详细配置(自己使用)
  13. 二叉树 java实现
  14. web前端优化--DOM性能优化
  15. Alibaba Cluster Data 开放下载:270GB 数据揭秘你不知道的阿里巴巴数据中心
  16. Pack
  17. Ansible 脚本运行一次后,再次运行时出现报错情况,原因:ansible script 的格式不对,应改成Unix编码
  18. MYSQL 创建数据库SQL
  19. 关于XCode工程中PrefixHead.pch文件的使用
  20. Mybatis的mapper文件中#和$的区别 以及 resultType和resultMap的区别

热门文章

  1. 用Maven插件生成Mybatis代码/数据库
  2. MyBatis多数据源配置(读写分离)
  3. ssh面试题
  4. js中document.documentElement 和document.body 以及其属性 clientWidth等
  5. overflow-x和overflow-y其中一个设置为visible时的奇怪现象
  6. jstack命令详解
  7. Django之表单字段的选填与后台界面的管理
  8. cas单点登录用户名为中文的解决办法
  9. CI框架初探
  10. mybatis中的oracle和mysql分页