zoukankan      html  css  js  c++  java
  • [BZOJ4548] 小奇的糖果

    问题描述

    平面上有n个点,每个点有一种颜色。对于某一条线段,选择所有其上方或下方的点。求:在不包含所有颜色的点的前提下,选择的点数最多是多少。(本题中如果存在某颜色没有相应的点,那么选择任何线段都不算做包含所有颜色)

    输入格式

    包含多组测试数据,第一行输入一个正整数 T 表示测试数据组数。

    接下来 T 组测试数据,对于每组测试数据,第一行输入两个正整数 N、K,分别表示点数和颜色数。

    接下来 N 行,每行描述一个点,前两个数 x, y (|x|, |y| ≤ 2^30 - 1) 描述点的位置,最后一个数 z (1 ≤ z ≤ k) 描述点的颜色。

    对于 100% 的数据,N ≤ 100000,K ≤ 100000,T ≤ 3

    输出格式

    对于每组数据在一行内输出一个非负整数 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

    解析

    题目的意思就是求一个不包含某一种颜色的点的区域,也就是求不包含这种颜色的极大子矩形。

    不妨先考虑求线段下方的点。那么,对于一个点,它的极大子矩形就是如下图所示的这样一个区域:

    其中ABC三点颜色相同,且BC是x坐标最靠近A的点。这样就保证了子矩形中没有与A颜色相同的点。那么怎样求点的数量呢?可以先离散化x坐标,然后用树状数组维护每个x坐标上有几个点即可。另外,要按y坐标从小到大加入树状数组中,保证每次求区间和时都是在线段以下的点。至于求一个点在x轴上最近的两点可以用STL的set实现。

    求线段上方的只需要将y坐标取相反数然后进行同样的操作即可。

    代码

    #include <iostream>
    #include <cstdio>
    #include <set>
    #include <algorithm>
    #include <cstring>
    #define int long long
    #define N 100002
    using namespace std;
    struct node{
    	int x,y,col;
    }a[N];
    int t,n,m,i,tmp[N],c[N],ans;
    int read()
    {
    	char c=getchar();
    	int w=0,f=1;
    	while(c<'0'||c>'9'){
    		if(c=='-') f=-1;
    		c=getchar();
    	}
    	while(c<='9'&&c>='0'){
    		w=w*10+c-'0';
    		c=getchar();
    	}
    	return w*f;
    }
    int my_comp(const node &a,const node &b)
    {
    	return a.y<b.y;
    }
    int lowbit(int x)
    {
    	return x&(-x);
    }
    void add(int x,int y)
    {
    	for(int i=x;i<=n;i+=lowbit(i)) c[i]+=y;
    }
    int ask(int x)
    {
    	int ans=0;
    	for(int i=x;i>=1;i-=lowbit(i)) ans+=c[i];
    	return ans;
    }
    void work()
    {
    	set<int> s[N];
    	int i=1,j=1;
    	memset(c,0,sizeof(c));
    	for(int i=1;i<=m;i++) s[i].insert(0),s[i].insert(n+1);
    	while(i<=n){
    		while(a[j].y==a[i].y) j++;
    		for(int k=i;k<j;k++){
    			int l=*(--s[a[k].col].upper_bound(a[k].x));
    			int r=*(s[a[k].col].lower_bound(a[k].x))-1;
    			ans=max(ans,ask(r)-ask(l));
    		}
    		for(int k=i;k<j;k++){
    			add(a[k].x,1);
    			s[a[k].col].insert(a[k].x);
    		}
    		i=j;
    	}
    	for(i=1;i<=m;i++){
    		set<int>::iterator it1=s[i].begin(),it2;
    		while(1){
    			it2=it1;it2++;
    			if(it2==s[i].end()) break;
    			ans=max(ans,ask((*it2)-1)-ask(*it1));
    			it1++;
    		}
    	}
    }
    signed main()
    {
    	t=read();
    	while(t--){
    		ans=0;
    		n=read();m=read();
    		for(i=1;i<=n;i++){
    			a[i].x=read(),a[i].y=read(),a[i].col=read();
    			tmp[i]=a[i].x;
    		}
    		sort(tmp+1,tmp+n+1);
    		int n1=unique(tmp+1,tmp+n+1)-tmp-1;
    		for(i=1;i<=n;i++) a[i].x=lower_bound(tmp+1,tmp+n1+1,a[i].x)-tmp;
    		sort(a+1,a+n+1,my_comp);
    		work();
    		for(i=1;i<=n;i++) a[i].y=-a[i].y;
    		sort(a+1,a+n+1,my_comp);
    		work();
    		printf("%lld
    ",ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    c语言结构体数组引用
    c语言结构体数组定义的三种方式
    如何为SAP WebIDE开发扩展(Extension),并部署到SAP云平台上
    SAP SRM ABAP Webdynpro和CFCA usb key集成的一个原型开发
    使用SAP API portal进行SAP SuccessFactors的API测试
    SAP UI5应用里的页面路由处理
    在SAP WebIDE Database Explorer里操作hdi实例
    如何使用SAP事务码SAT进行UI应用的性能分析
    使用SAP WebIDE进行SAP Cloud Platform Business Application开发
    SAP CRM WebClient UI ON_NEW_FOCUS的用途
  • 原文地址:https://www.cnblogs.com/LSlzf/p/11691366.html
Copyright © 2011-2022 走看看