zoukankan      html  css  js  c++  java
  • bzoj4548: 小奇的糖果

    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,表示答案

    枚举哪种颜色不选

    存在一个最优解,使所选区域三边都  紧靠着不可选的点 或 可延伸到无限远

    找出符合这个条件的O(n)个区域,用扫描线求出点数

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define G *++ptr
    const int N=100007;
    char buf[N*100],*ptr=buf-1;
    int _(){
        int x=0,c=G,f=1;
        while(c<48)c=='-'&&(f=-1),c=G;
        while(c>47)x=x*10+c-48,c=G;
        return x*f;
    }
    int n,k,ans;
    struct pos{
        int x,y,c;
        bool operator<(const pos&w)const{return x<w.x;}
    }ps[N];
    bool cmp(const pos&a,const pos&b){return a.y<b.y;}
    struct pt{
        int x,y;
    }mem[N],*mp,*ls[N],*rs[N];
    struct Q{
        int y,l,r;
    }qs1[N],qs2[N];
    bool cmp1(const Q&a,const Q&b){return a.y>b.y;}
    bool cmp2(const Q&a,const Q&b){return a.y<b.y;}
    int xs[N],ys[N],cs[N],bit[N],ts[N],qp1,qp2;
    void inc(int w){
        for(;w<=n;w+=w&-w)++bit[w];
    }
    int sum(int w){
        int s=0;
        for(;w;w-=w&-w)s+=bit[w];
        return s;
    }
    void mins(int&a,int b){if(a>b)a=b;}
    void maxs(int&a,int b){if(a<b)a=b;}
    pt p1[N],p2[N];
    int pp1,pp2,ss[N],sp,l1[N],r1[N],l2[N],r2[N];
    void cal(pt*l,pt*r){
        if(l==r){
            ans=n;
            return;
        }
        pp1=pp2=0;
        maxs(ans,ts[l->x-1]);
        maxs(ans,ts[n]-ts[r[-1].x]);
        for(pt*m=l;l<r;l=m){
            int ymx=l->y,ymn=l->y;
            while(m<r&&m->x==l->x)maxs(ymx,m->y),mins(ymn,m->y),++m;
            if(m<r)maxs(ans,ts[m->x-1]-ts[l->x]);
            p1[++pp1]=(pt){l->x,ymx};
            p2[++pp2]=(pt){l->x,ymn};
        }
        sp=0;
        
        for(int i=1;i<=pp1;++i){
            while(sp&&p1[ss[sp]].y<p1[i].y)r1[ss[sp--]]=p1[i].x-1;
            ss[++sp]=i;
        }
        while(sp)r1[ss[sp--]]=n;
        for(int i=pp1;i;--i){
            while(sp&&p1[ss[sp]].y<p1[i].y)l1[ss[sp--]]=p1[i].x+1;
            ss[++sp]=i;
        }
        while(sp)l1[ss[sp--]]=1;
        for(int i=1;i<=pp1;++i)qs1[qp1++]=(Q){p1[i].y,l1[i],r1[i]};
        
        for(int i=1;i<=pp2;++i){
            while(sp&&p2[ss[sp]].y>p2[i].y)r2[ss[sp--]]=p2[i].x-1;
            ss[++sp]=i;
        }
        while(sp)r2[ss[sp--]]=n;
        for(int i=pp2;i;--i){
            while(sp&&p2[ss[sp]].y>p2[i].y)l2[ss[sp--]]=p2[i].x+1;
            ss[++sp]=i;
        }
        while(sp)l2[ss[sp--]]=1;
        for(int i=1;i<=pp2;++i)qs2[qp2++]=(Q){p2[i].y,l2[i],r2[i]};
    }
    int main(){
        fread(buf,1,sizeof(buf),stdin)[buf]=0;
        for(int T=_();T;--T){
            n=_();k=_();
            ans=0;qp1=qp2=0;
            memset(cs,0,sizeof(int)*(k+2));
            memset(ts,0,sizeof(int)*(n+2));
            mp=mem;
            for(int i=1;i<=n;++i){
                ps[i].x=xs[i]=_();
                ps[i].y=ys[i]=_();
                ++cs[ps[i].c=_()];
            }
            std::sort(xs+1,xs+n+1);
            std::sort(ys+1,ys+n+1);
            for(int i=1;i<=n;++i){
                ps[i].x=std::lower_bound(xs+1,xs+n+1,ps[i].x)-xs;
                ps[i].y=std::lower_bound(ys+1,ys+n+1,ps[i].y)-ys;
                ++ts[ps[i].x];
            }
            std::sort(ps+1,ps+n+1);
            for(int i=1;i<=n;++i)ts[i]+=ts[i-1];
            for(int i=1;i<=k;++i)ls[i]=rs[i]=mp,mp+=cs[i];
            for(int i=1;i<=n;++i)*rs[ps[i].c]++=(pt){ps[i].x,ps[i].y};
            for(int i=1;i<=k;++i)cal(ls[i],rs[i]);
            std::sort(ps+1,ps+n+1,cmp);
            std::sort(qs1,qs1+qp1,cmp1);
            std::sort(qs2,qs2+qp2,cmp2);
            memset(bit,0,sizeof(int)*(n+2));
            for(int i=0,j=n;i<qp1;++i){
                while(j&&ps[j].y>qs1[i].y)inc(ps[j--].x);
                int z;
                maxs(ans,z=sum(qs1[i].r)-sum(qs1[i].l-1));
            }
            memset(bit,0,sizeof(int)*(n+2));
            for(int i=0,j=1;i<qp2;++i){
                while(j<=n&&ps[j].y<qs2[i].y)inc(ps[j++].x);
                maxs(ans,sum(qs2[i].r)-sum(qs2[i].l-1));
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    maven pom 详细配置
    寻找二叉树最远的叶子结点
    控制两个线程的启动顺序
    tensorflow之神经网络实现流程总结
    ubuntu服务器安装FTP服务
    ubuntu服务器 安装 seafile 个人网盘
    软件工程实践总结作业~
    Beta 答辩总结
    Beta 冲刺 (7/7)
    Beta 冲刺 (6/7)
  • 原文地址:https://www.cnblogs.com/ccz181078/p/6574696.html
Copyright © 2011-2022 走看看