zoukankan      html  css  js  c++  java
  • 【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
    ",ans);
        }
        return 0;
    }
    
  • 相关阅读:
    [转载]数据库外键的使用
    [转载]我如何筛选简历与选择人员
    [转载]asp.net中使用Row_Number函数分页
    五一,给心情放个假酷狗电台桌面版
    win32建立弹出式菜单
    GetMessage用法错误导致程序不能退出
    win32在程序当中引用菜单
    WM_COMMAND和WM_KEYDOWN消息的wParam,lParam参数
    单链表的释放内存free(delete)的顺序
    win32 GetMenu()和GetSubMenu()
  • 原文地址:https://www.cnblogs.com/fexuile/p/11691126.html
Copyright © 2011-2022 走看看