• 小奇的糖果(candy)



    【题目背景】
    小奇不小心让糖果散落到了地上,它对着满地的彩色糖果胡思乱想。
    【问题描述】
    有 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

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstdlib>
      4 #include<cmath>
      5 #include<algorithm>
      6 #include<cstring>
      7 #include<queue>
      8 #include<vector>
      9 #include<set>
     10 using namespace std;
     11 typedef long long LL;
     12 const int maxn=100010;
     13 int T,ANS,N,K;
     14 int last[maxn],l[maxn],r[maxn];
     15 int disc[maxn],x[maxn],b[maxn];
     16 struct Candy{
     17     int x,y,k;
     18     int id;
     19 }a[maxn];
     20 inline int cmpbyy(const Candy & w,const Candy & e){//´Óϵ½ÉÏ ´Ó×óµ½ÓÒ 
     21     return w.y<e.y||(w.y==e.y&&w.x<e.x);
     22 }
     23 inline int cmpbyx(const Candy & w,const Candy & e){//´Ó×óµ½ÓÒ ´Óϵ½ÉÏ 
     24     return w.x<e.x||(w.x==e.x&&w.y>e.y);
     25 }
     26 struct Tree{
     27     int l,r,sum;
     28 }tr[maxn*8];
     29 inline void Build(int rt,int l,int r){
     30     tr[rt].l=l; tr[rt].r=r;
     31     if(l==r){
     32         tr[rt].sum=b[l];
     33         return ;
     34     }
     35     int mid=(l+r)>>1;
     36     Build(rt<<1,l,mid); Build(rt<<1|1,mid+1,r);
     37     tr[rt].sum=tr[rt<<1].sum+tr[rt<<1|1].sum;
     38 }
     39 inline void change(int rt,int pos,int delta){
     40     if(tr[rt].l==tr[rt].r){
     41         tr[rt].sum+=delta;
     42         return ;
     43     }
     44     int mid=(tr[rt].l+tr[rt].r)>>1;
     45     if(pos<=mid) change(rt<<1,pos,delta);
     46     else change(rt<<1|1,pos,delta);
     47     tr[rt].sum=tr[rt<<1].sum+tr[rt<<1|1].sum;
     48 }
     49 inline int query(int rt,int l,int r){
     50     if(l<=tr[rt].l&&tr[rt].r<=r){
     51         return tr[rt].sum;
     52     }
     53     int mid=(tr[rt].l+tr[rt].r)>>1;
     54     int ans=0;
     55     if(l<=mid) ans+=query(rt<<1,l,r);
     56     if(mid+1<=r) ans+=query(rt<<1|1,l,r);
     57     return ans;
     58 }
     59 inline void update(int l,int r){
     60     if(l>r) return ;
     61     ANS=max(ANS,query(1,l,r));
     62 }
     63 inline void work(){
     64     x[0]=0; x[N+1]=N+1;
     65     memset(last,0,sizeof(last)); memset(b,0,sizeof(b));
     66     for(int i=1;i<=800000;i++) tr[i].l=tr[i].r=tr[i].sum=0;
     67     
     68     sort(a+1,a+N+1,cmpbyx);
     69     for(int i=1;i<=N;i++) b[x[i]]++;
     70     Build(1,1,N+1);
     71     for(int i=1;i<=N;i++){
     72         int tmp=a[i].id,L=last[a[i].k];
     73         l[tmp]=L; r[tmp]=N+1;
     74         if(L) r[L]=tmp;
     75         update(x[L]+1,x[tmp]-1);
     76         last[a[i].k]=tmp;
     77     }
     78     for(int i=1;i<=K;i++){
     79         update(x[last[i]]+1,N+1);
     80     }
     81     sort(a+1,a+N+1,cmpbyy);
     82     for(int i=1,j=1;i<=N;i++){
     83         int tmp=a[i].id;
     84         while(j<=N&&a[j].y==a[i].y){
     85             change(1,a[j].x,-1);
     86             j++;
     87         }
     88         l[r[tmp]]=l[tmp]; r[l[tmp]]=r[tmp];
     89         update(x[l[tmp]]+1,x[r[tmp]]-1);
     90     }
     91 }
     92 int main(){
     93 //    freopen("candy.in","r",stdin);
     94 //    freopen("candy.out","w",stdout);
     95     scanf("%d",&T);
     96     while(T--){
     97         ANS=0;
     98         scanf("%d%d",&N,&K);
     99         for(int i=1;i<=N;i++){
    100             scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].k);
    101             a[i].id=i;
    102         }
    103         for(int i=1;i<=N;i++){
    104             disc[i]=a[i].x;
    105         }
    106         sort(disc+1,disc+N+1);
    107         int *end=unique(disc+1,disc+N+1);
    108         for(int i=1;i<=N;i++){
    109             a[i].x=lower_bound(disc+1,end,a[i].x)-disc;
    110             x[i]=a[i].x;
    111         }
    112         work();
    113         for(int i=1;i<=N;i++) a[i].y*=-1;
    114         work();
    115         printf("%d
    ",ANS);
    116     }
    117     return 0; 
    118 }
  • 相关阅读:
    【java基础 11】java集合框架学习
    【java基础 10】hash算法冲突解决方法
    【java 基础 9】原来我从没有了解过String类
    阳光总在风雨后——研究生考后总结
    【java基础 8】垃圾收集算法及内存分配策略
    【java基础 7】java内存区域分析及常见异常
    【java基础 6】java的发展史简介
    springboot的使用体验和思考
    大道至简——你比你想象中更早接触微服务
    【Ts 3】Nginx的Http(图片)服务器配置+ftp上传使用说明
  • 原文地址:https://www.cnblogs.com/CXCXCXC/p/5319352.html
Copyright © 2020-2023  润新知