bzoj 2288: POJ Challenge生日礼物链表+堆

Posted lokiii

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj 2288: POJ Challenge生日礼物链表+堆相关的知识,希望对你有一定的参考价值。

参考:http://blog.csdn.net/w_yqts/article/details/76037315
把相同符号的连续数字加起来,合并后ans先贪心的加上所有正数,如果正数个数sum>m,设计二元组(i,a[i])表示合并后序列i位置上值为a,记录前驱后继,塞进按绝对值排序的小根堆里。每次拿出来一个,减去这个x的a的绝对值,然后合并左右前驱后继,再塞回去。
如果拿出来的是正数,那么减去相当于原来选了现在不选,如果是负数,减去相当于选。
然后a值要改成a[l]+a[r]+a[x],下次再选这个区间的话,相当于对x进行逆操作。
注意边界,边界上的负数没用。

#include<iostream>
#include<cstdio>
#include<queue>
#include<algorithm>
using namespace std;
const int N=100005,inf=1e9;;
int n,m,a[N],tot=1,ne[N],pr[N],ans,sum;
bool v[N];
// priority_queue<pair<int,int> >q;
struct cmp
{
    bool operator()(pair<int,int> a,pair<int,int> b)
    {
        return abs(a.first)>abs(b.first);
    }
};
priority_queue<pair<int,int>,vector<pair<int,int> >,cmp>q;
int read()
{
    int r=0,f=1;
    char p=getchar();
    while(p>‘9‘||p<‘0‘)
    {
        if(p==‘-‘)
            f=-1;
        p=getchar();
    }
    while(p>=‘0‘&&p<=‘9‘)
    {
        r=r*10+p-48;
        p=getchar();
    }
    return r*f;
}
int main()
{
    n=read(),m=read();
    for(int i=1;i<=n;i++)
    {
        int x=read();
        if((long long)a[tot]*x>=0)
            a[tot]+=x;
        else
            a[++tot]=x;
    }
    for(int i=1;i<=tot;i++)
    {//cout<<a[i]<<endl;
        if(a[i]>0)
            ans+=a[i],sum++;
        pr[i]=i-1;
        ne[i]=i+1;
        q.push(make_pair(a[i],i));
    }
    pr[1]=0,ne[tot]=0;
    while(sum>m)
    {
        sum--;
        while(v[q.top().second])
            q.pop();
        int x=q.top().second,l=pr[x],r=ne[x];
        q.pop();
        if(l&&r)
            ans-=abs(a[x]);
        else if(a[x]>0)
            ans-=a[x];
        else
        {
            sum++;//边界上的负数不能取,要把减去的sum加回来
            continue;
        }
        a[x]=a[l]+a[r]+a[x];
        v[l]=1;v[r]=1;
        pr[ne[l]]=pr[l],pr[ne[r]]=pr[r];
        ne[pr[l]]=ne[l],ne[pr[r]]=ne[r];
        q.push(make_pair(a[x],x));
    }
    printf("%d\n",ans);
    return 0;
}

以上是关于bzoj 2288: POJ Challenge生日礼物链表+堆的主要内容,如果未能解决你的问题,请参考以下文章

[bzoj2288][POJ Challenge]生日礼物

bzoj2288 POJ Challenge生日礼物

BZOJ 2288 POJ Challenge生日礼物(贪心+优先队列)

bzoj 2288: POJ Challenge生日礼物链表+堆

BZOJ3502/2288PA2012 Tanie linie/POJ Challenge生日礼物 堆+链表(模拟费用流)

bzoj2287 [POJ Challenge]消失之物