zoukankan      html  css  js  c++  java
  • 【BZOJ-4548&3658】小奇的糖果&Jabberwocky 双向链表 + 树状数组

    4548: 小奇的糖果

    Time Limit: 10 Sec  Memory Limit: 256 MB
    Submit: 103  Solved: 47
    [Submit][Status][Discuss]

    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

    HINT

    Source

    By Hzwer

    3658: Jabberwocky

    Time Limit: 20 Sec  Memory Limit: 1024 MB
    Submit: 178  Solved: 73
    [Submit][Status][Discuss]

    Description

    平面上有n个点,每个点有k种颜色中的一个。
    你可以选择一条水平的线段获得在其上方或其下方的所有点,如图所示:

    请求出你最多能够得到多少点,使得获得的点并不包含所有的颜色。
       

    Input

    包含多组测试数据,第一行输入一个数T表示测试数据组数。
        接下来T组测试数据,对于每组测试数据,第一行输入两个数n,k,分别表示点的个数和颜色数。
        接下来n行每行描述一个点,前两个数z,y(lxl,lyl≤2^32-1)描述点的位置,最后一个数z(1≤z≤K)描述点的颜色。
       

    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

    HINT

    N<=100000,K<=100000,T<=3

    Source

    Solution

    思路比较好的题,本来以为可以转化成某种扫描线,但是无果

    首先,按y坐标排序,我们假定这条线无限低,这时候答案相当于相邻两个同种颜色的中间的最大点数

    然后这条线向上,一次性删除一行

    用双向链表维护一个点的前一个和后一个同种颜色的位置

    删除的话,把这个点从树状数组和链表中都删除,每次删除,统计一下这个点之前相邻的和之后相邻的答案

    然后把y全都赋成相反数,再做一遍即可得到下端的情况

    Code

    #include<iostream> 
    #include<cstdio> 
    #include<cstring> 
    #include<algorithm> 
    #include<cmath> 
    using namespace std; 
    int read() 
    { 
        int x=0,f=1; char ch=getchar(); 
        while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();} 
        while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();} 
        return x*f; 
    } 
    #define MAXN 1000010 
    int T,N,K,ans; 
    struct PointNode{int x,y,c,id;}P[MAXN]; 
    int ls[MAXN],tp,top; 
    struct lkList{int last,nxt,now;}lk[MAXN]; 
    int C[MAXN]; 
    struct BIT 
    { 
        int tree[MAXN]; 
        void Init() {memset(tree,0,sizeof(tree));}
        int lowbit(int x) {return x&(-x);} 
        void Add(int pos,int D) 
            { 
                for (int i=pos; i<=top+1; i+=lowbit(i))  
                    tree[i]+=D; 
            }    
        int Query(int pos) 
            { 
                int re=0; 
                for (int i=pos; i; i-=lowbit(i)) 
                    re+=tree[i]; 
                return re; 
            } 
        int Query(int L,int R) {if (R<L) return 0; else return Query(R)-Query(L-1);} 
    }bit; 
    bool cmpY(PointNode A,PointNode B) {return A.y<B.y;} 
    bool cmpX(PointNode A,PointNode B) {return A.x<B.x;} 
    void Solve() 
    { 
        bit.Init();
        memset(C,0,sizeof(C)); 
        sort(P+1,P+N+1,cmpX); lk[N+1].now=top+1;
        for (int i=1; i<=N; i++) bit.Add(P[i].x,1); 
        for (int i=1; i<=N; i++) 
            { 
                P[i].id=i;
                lk[i].last=C[ P[i].c ]; lk[i].nxt=N+1; lk[i].now=P[i].x; 
                if (C[ P[i].c ]) lk[ C[ P[i].c ] ].nxt=i; 
                C[ P[i].c ]=i;  
                ans=max(ans,bit.Query(P[ lk[i].last ].x+1,P[i].x-1)); 
            } 
    //  printf("Ans1=%d
    ",ans); 
        sort(P+1,P+N+1,cmpY); 
        for (int i=1; i<=K; i++)  
            ans=max(ans,bit.Query(lk[ C[i] ].now+1,top+1)); 
    //  printf("Ans2=%d
    ",ans); 
        for (int t=1,i=1; i<=N; i++) 
            { 
                int now=P[i].id; 
                while (t<=N && P[t].y==P[i].y) 
                    bit.Add(P[t].x,-1),t++; 
                if (lk[now].nxt) lk[ lk[now].nxt ].last=lk[now].last; 
                if (lk[now].last) lk[ lk[now].last ].nxt=lk[now].nxt; 
                ans=max(ans,bit.Query(lk[ lk[now].last ].now+1,lk[ lk[now].nxt ].now-1)); 
                lk[now].nxt=lk[now].last=0;
            } 
    //  printf("Ans3=%d
    ",ans); 
    } 
    int main() 
    { 
        T=read(); 
        while (T--) 
            { 
                N=read(),K=read(); 
                ans=0; 
                for (int i=1; i<=N; i++)  
                    ls[++tp]=P[i].x=read(),P[i].y=read(),P[i].c=read(),P[i].id=i; 
                sort(ls+1,ls+tp+1); 
                top=unique(ls+1,ls+tp+1)-ls-1;
                for (int i=1; i<=N; i++) P[i].x=lower_bound(ls+1,ls+top+1,P[i].x)-ls; 
                //for (int i=1; i<=N; i++) printf("x=%d
    ",P[i].x); 
                Solve(); 
                for (int i=1; i<=N; i++) P[i].y=-P[i].y; 
                Solve(); 
                printf("%d
    ",ans); 
            } 
        return 0; 
    }
  • 相关阅读:
    shell 指令
    在Linux下搭建nRF51822的开发烧写环境(makefile版)
    宏定义。字符串拼接和字符串整形转字符串
    django-debug-toolbar安装过程中的error
    pipenv
    Docker 命令大全
    MySQL性能优化
    docker操作
    使用网易源解决docker下载镜像文件慢的问题
    w3school/jQuery 教程
  • 原文地址:https://www.cnblogs.com/DaD3zZ-Beyonder/p/5782207.html
Copyright © 2011-2022 走看看