【BZOJ4548】小奇的糖果

【BZOJ4548】小奇的糖果

传送门

BZOJ

Solution

如果你觉得这道题目比较奇怪,请认真审题

线段不是直线

我们可以强制一种颜色不选,因为多种颜色不选一定不会比一种颜色不选优,此时考虑选取的颜色情况:

  1. 选取两个相邻颜色中间的颜色
  2. 将最上面的颜色删除,选取他下面两个相邻的颜色中间的。

注意这个可以排序+树状数组维护。

Code

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<queue>
#include<iostream>
using namespace std;
inline int gi(){
    int sum=0,f=1;char ch=getchar();
    while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0' && ch<='9'){sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}
    return f*sum;
}
int ans,n,K,c[500010],x[500010],l[500010],r[500010],last[500010],b[500010];
struct node{
    int id,x,y,z;
}p[500010];
int lowbit(int x){
    return x&-x;
}
void add(int x,int d){
    for(;x<=n+1;x+=lowbit(x))c[x]+=d;
}
int query(int x){
    int res=0;
    for(;x>0;x-=lowbit(x))res+=c[x];
    return res;
}
bool cmp1(node a,node b){
    return a.x<b.x;
}
bool cmp2(node a,node b){
    return a.y<b.y;
}
void update(int l,int r){
    if(l>r)return;
    ans=max(ans,query(r)-query(l-1));
}
void solve(){
    x[0]=0;x[n+1]=n+1;
    memset(c,0,sizeof(c));memset(last,0,sizeof(last));
    sort(p+1,p+n+1,cmp1);
    for(int i=1;i<=n;i++)add(p[i].x,1);
    for(int i=1;i<=n;i++){
        int t=p[i].id,L=last[p[i].z];
        l[t]=L;r[t]=n+1;
        if(L)r[L]=t;update(x[L]+1,x[t]-1);
        last[p[i].z]=t;
    }
    for(int i=1;i<=K;i++)update(x[last[i]]+1,n+1);
    sort(p+1,p+n+1,cmp2);
    for(int i=1,j=1;i<=n;i++){
        int t=p[i].id;
        while(j<=n && p[i].y==p[j].y)add(p[j].x,-1),j++;
        l[r[t]]=l[t];r[l[t]]=r[t];
        update(x[l[t]]+1,x[r[t]]-1);
    }
}
int main(){
#ifndef ONLINE_JUDGE
    freopen("in.in","r",stdin);
    freopen("out.out","w",stdout);
#endif
    int T=gi();
    while(T--){
        ans=0;
        n=gi();K=gi();
        for(int i=1;i<=n;i++){
            p[i].x=gi();p[i].y=gi();p[i].z=gi();
            p[i].id=i;
        }
        for(int i=1;i<=n;i++)b[i]=p[i].x;
        sort(&b[1],&b[n+1]);
        for(int i=1;i<=n;i++){
            p[i].x=lower_bound(b+1,b+n+1,p[i].x)-b;
            x[i]=p[i].x;
        }
        solve();
        for(int i=1;i<=n;i++)p[i].y=-p[i].y;
        solve();
        printf("%d\n",ans);
    }
    return 0;
}
posted @ 2019-10-17 11:46  fexuile  阅读(163)  评论(0编辑  收藏  举报