bzoj4576 [Usaco2016 Open]262144

题目大意:

给出n个数a[1..n],n<=262144,a[i]<=40,相邻且相同的数可以合并成一个并将值加1,问能获得的最大数是多少

用一个双向链表维护原数列,每个节点记录此节点对应的数值和数的个数,合并相邻且对应数值相同的节点

每次选一个数值最小的点处理,此时两侧的数都更大

若这个点只有一个数则直接删去并断开两侧,此时两侧的数不可能再互相合并

若这个点有偶数个数则数值+1,个数/2,检测能否和两侧合并

若这个点有奇数个数,两侧的数也不可能再互相合并了,因此将这个点分裂成两个互不相连的点,数值+1,(个数-1)/2,分别与两侧连接

可以证明时空复杂度均为O(n)

#include<cstdio>
#include<vector>
inline int input(){
    int x=0,c=getchar();
    while(c>57||c<48)c=getchar();
    while(c>47&&c<58)x=x*10+c-48,c=getchar();
    return x;
}
const int N=1000000;
std::vector<int>q[128];
int nx[N],pv[N],v[N],t[N],p=0,ans=0,n;
int main(){
    n=input();
    for(int i=1,a=-1,b;i<=n;i++){
        b=input();
        if(a!=b)v[++p]=b;
        ++t[p];
        a=b;
    }
    for(int i=1;i<=p;i++){
        pv[i]=i-1;
        nx[i]=i+1;
        q[v[i]].push_back(i);
    }
    nx[p]=0;
    for(int i=1;i<100;i++){
        for(int j=0,sz=q[i].size();j<sz;j++){
            int w=q[i][j];
            if(!t[w])continue;
            if(t[w]==1){
                nx[pv[w]]=pv[nx[w]]=0;
                t[w]=0;
            }else if(t[w]&1){
                int _t=t[w]>>1,_pv=pv[w],_nx=nx[w],_v=v[w]+1;
                t[w]=0;
                if(v[_pv]==_v){
                    t[_pv]+=_t;
                    pv[_nx]=nx[_pv]=0;
                }else{
                    nx[_pv]=++p;
                    pv[p]=_pv;
                    t[p]=_t;
                    v[p]=_v;
                    q[_v].push_back(p);
                }
                if(v[_nx]==_v){
                    t[_nx]+=_t;
                    pv[_nx]=nx[_pv]=0;
                }else{
                    pv[_nx]=++p;
                    nx[p]=_nx;
                    t[p]=_t;
                    v[p]=_v;
                    q[_v].push_back(p);
                }
            }else{
                int _t=t[w]>>1,_pv=pv[w],_nx=nx[w],_v=v[w]+1;
                t[w]=0;
                if(v[_pv]==_v){
                    if(v[_nx]==_v){
                        t[_pv]+=t[_nx]+_t;
                        t[_nx]=0;
                        pv[nx[_pv]=nx[_nx]]=_pv;
                    }else{
                        t[_pv]+=_t;
                        pv[_nx]=_pv;
                        nx[_pv]=_nx;
                    }
                }else if(v[_nx]==_v){
                    t[_nx]+=_t;
                    pv[_nx]=_pv;
                    nx[_pv]=_nx;
                }else{
                    t[w]=_t;
                    v[w]=_v;
                    q[_v].push_back(w);
                }
            }
        }
    }
    for(int i=1;i<=p;i++)if(v[i]>ans)ans=v[i];
    printf("%d",ans);
    return 0;
}
时间: 2024-11-12 09:03:15

bzoj4576 [Usaco2016 Open]262144的相关文章

BZOJ 4576: [Usaco2016 Open]262144

Description 一个序列,每次可以将两个相同的数合成一个数,价值+1,求最后最大价值 \(n \leqslant 262144\) Sol DP. 这道题是 BZOJ 4580: [Usaco2016 Open]248 加强版. 做248的那个区间DP其实很多方案都是0,而且一个区间中只有一个合法的数字. 然后就是 一个区间合成一个数的方案的这个数字是固定的. \(f[i][j]\) 表示以 \(i\) 结尾是否能合成 \(j\),同时记录一下转移位置,每次向前找前一个指针就可以了. 复

bzoj4576【Usaco2016 Open】262144

4576: [Usaco2016 Open]262144 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 97  Solved: 73 [Submit][Status][Discuss] Description Bessie likes downloading games to play on her cell phone, even though she does find the small touch screen rather cumbe

USACO 2016 US Open Contest 262144 (bzoj4576)

262144 (262144) Description Bessie喜欢在她的手机上下载游戏玩,尽管她发现她的大蹄使用小触摸屏幕相当麻烦.她特别感兴趣的是她正在玩 的游戏. 游戏从一个有N个正整数的序列开始(2≤N≤262,144),每个数字在1...40的范围内. 在一个步骤中, Bessie可以获取具有相等值的两个相邻数字,并且用比这两个数大一的值替换这两个数值(例如,她可以用8替换 两个相邻的7).目标是在游戏结束时最大化在序列中存在的最大数字的值. 请帮助Bessie得分尽可能高! 题目

BZOJ 4742: [Usaco2016 Dec]Team Building

4742: [Usaco2016 Dec]Team Building Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 21  Solved: 16[Submit][Status][Discuss] Description Every year, Farmer John brings his NN cows to compete for "best in show" at the state fair. His arch -rival, F

bzoj4509【Usaco2016 Jan】Angry Cows

4509: [Usaco2016 Jan]Angry Cows Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 83  Solved: 38 [Submit][Status][Discuss] Description Bessie the cow has designed what she thinks will be the next big hit video game: "Angry Cows". The premise, whi

4582: [Usaco2016 Open]Diamond Collector

4582: [Usaco2016 Open]Diamond Collector Description Bessie the cow, always a fan of shiny objects, has taken up a hobby of mining diamonds in her spare time! She has collected N diamonds (N≤50,000) of varying sizes, and she wants to arrange some of t

bzoj4745: [Usaco2016 Dec]Cow Checklist

bzoj4745: [Usaco2016 Dec]Cow Checklist Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1  Solved: 1[Submit][Status][Discuss] Description Every day, Farmer John walks through his pasture to check on the well-being of each of his cows. Onh is farm he h

bzoj4580: [Usaco2016 Open]248

bzoj4580: [Usaco2016 Open]248 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 23  Solved: 21[Submit][Status][Discuss] Description Bessie likes downloading games to play on her cell phone, even though she does find the small touch screen rather cumber

bzoj 4412: [Usaco2016 Feb]Circular Barn

4412: [Usaco2016 Feb]Circular Barn Description 有一个N个点的环,相邻两个点距离是1.点顺时针标号为1..N.每一个点有ci头牛,保证∑ci=N.每头牛都可以顺时针走.设一头牛走了d个单位停下了,将耗费d^2的能量.请设计一种牛的走法,使得每一个点上都正好有一头牛,且最小化耗费的能量. Input 第一行一个数N.N <= 100000接下来N行,每行一个数ci. Output 输出一个数表示耗费能量的最小值 Sample Input 10 1 0