• BZOJ4548 小奇的糖果


    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作。

     

    本文作者:ljh2000
    作者博客:http://www.cnblogs.com/ljh2000-jump/
    转载请注明出处,侵权必究,保留最终解释权!

     

     

    Description

    有 N 个彩色糖果在平面上。小奇想在平面上取一条水平的线段,并拾起它上方或下方的所有糖果。求出最多能够拾

    起多少糖果,使得获得的糖果并不包含所有的颜色。

    Input

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

    接下来 T 组测试数据,对于每组测试数据,第一行输入两个正整数 N、K,分别表示点数和颜色数。
    接下来 N 行,每行描述一个点,前两个数 x, y (|x|, |y| ≤ 2^30 - 1) 描述点的位置,最后一个数 z (1 ≤ z ≤
     k) 描述点的颜色。
    对于 100% 的数据,N ≤ 100000,K ≤ 100000,T ≤ 3

    Output

    对于每组数据在一行内输出一个非负整数 ans,表示答案

     

     

    Sample Input

    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

    Sample Output

    5
     
     
    正解:树状数组+双向链表
    解题报告:
         注意题目中说的是线段而不是直线,若是直线的话线性扫一遍即可。
      那么对于这道题,如果单独考虑一种颜色,那么讲这种颜色的所有点按x排序之后,假设相邻两个点的横坐标分别为p,q,则[p+1,q-1]中一定再没有这种颜色的糖果,这个证明的话可以显然。
      由于题目要求不包含所有的糖果的情况下可以取到的最大糖果数量,显然[p+1,q-1]区间内的点一定满足题意。
      依据上述结论,不难得出具体做法:按y轴从小到大排序,从下往上处理,先默认我们只取线段以上的部分(以下的部分可以把纵坐标反号再做一次),可以想象成是一根直线往上推进,每当我扫描到一个点,就可以考虑用与这个点颜色相同的左右两个点之间的部分更新答案,正确性上面已经证明了。同时消除这个点的影响。
      不妨用树状数组维护区间数量,双向链表维护颜色相同的左右两个点,这样的话可以在nlogn的时间里完成操作。
     
     
    //It is made by ljh2000
    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    #include <ctime>
    #include <vector>
    #include <queue>
    #include <map>
    #include <set>
    #include <string>
    using namespace std;
    typedef long long LL;
    const int MAXN = 100011;
    int n,C[MAXN],L,k,yan[MAXN],ans,X[MAXN];
    int last[MAXN],next[MAXN],c[MAXN];
    struct node{int x,y,col,pos;}a[MAXN];
    inline bool cmpx(node q,node qq){ if(q.x==qq.x) return q.y>qq.y; return q.x<qq.x; }
    inline bool cmpy(node q,node qq){ return q.y<qq.y; }
    inline void add(int x,int val){ while(x<=L) c[x]+=val,x+=x&(-x); } 
    inline int query(int x){ if(x==0) return 0; int tot=0; while(x>0) tot+=c[x],x-=x&(-x); return tot; }
    inline void update(int l,int r){ if(l>r) return ; int tot=query(r)-query(l-1); if(tot>ans) ans=tot; }
    inline int getint(){
        int w=0,q=0; char c=getchar(); while((c<'0'||c>'9') && c!='-') c=getchar();
        if(c=='-') q=1,c=getchar(); while (c>='0'&&c<='9') w=w*10+c-'0',c=getchar(); return q?-w:w;
    }
    
    inline void solve(){
    	X[0]=0; X[n+1]=L; memset(last,0,sizeof(last)); memset(next,0,sizeof(next)); memset(yan,0,sizeof(yan));
    	for(int i=1;i<=n;i++) add(a[i].x,1); sort(a+1,a+n+1,cmpx);
    	for(int i=1;i<=n;i++) {
    		last[a[i].pos]=yan[a[i].col]; next[a[i].pos]=n+1;
    		if(yan[a[i].col]) next[yan[a[i].col]]=a[i].pos;
    		update(X[yan[a[i].col]]+1,X[a[i].pos]-1);
    		yan[a[i].col]=a[i].pos;
    	}
    	for(int i=1;i<=k;i++) update(X[yan[i]]+1/*!!!*/,L);
    	sort(a+1,a+n+1,cmpy);
    	for(int i=1,head=1;i<=n;i=head) {
    		while(head<=n && a[head].y==a[i].y) {
    			add(a[head].x,-1);
    			head++;
    		}	  		
    		for(int j=i;j<head;j++) {
    			update(X[last[a[j].pos]]+1,X[next[a[j].pos]]-1); 
    			next[last[a[j].pos]]=next[a[j].pos]; 
    			last[next[a[j].pos]]=last[a[j].pos];
    		}	 
    	}
    }
    
    inline void work(){
    	int T=getint(); 
    	while(T--) {
    		n=getint(); k=getint(); ans=0; L=0; for(int i=1;i<=n;i++) a[i].x=getint(),a[i].y=getint(),a[i].col=getint(),C[i]=a[i].x,a[i].pos=i;
    		sort(C+1,C+n+1); L=unique(C+1,C+n+1)-C-1; for(int i=1;i<=n;i++) a[i].x=lower_bound(C+1,C+L+1,a[i].x)-C,X[i]=a[i].x; L++;
    		solve(); for(int i=1;i<=n;i++) a[i].y=-a[i].y;	solve();
    		printf("%d
    ",ans);
    	}
    }
    
    int main()
    {
        work();
        return 0;
    }
    

      

      

     
  • 相关阅读:
    Spring Boot 入门实战(7)--JdbcTempalte、Mybatis、动态数据源及 Atomicos 整合(XA 事务)
    L1-058 6翻了 (15 分)
    L1-057 PTA使我精神焕发 (5 分)
    L1-056 猜数字 (20 分)
    L1-055 谁是赢家 (10 分)
    L1-054 福到了 (15 分)
    L1-053 电子汪 (10 分)
    L1-052 2018我们要赢 (5 分)
    L1-051 打折 (5 分)
    L1-050 倒数第N个字符串 (15 分)
  • 原文地址:https://www.cnblogs.com/ljh2000-jump/p/6201857.html
Copyright © 2020-2023  润新知