bzoj1150: [CTSC2007]数据备份Backup

en跟前面那个种树的一样嘛

只是不是环,就在左右两边设INF的边界就好了。(mdzz(1<<31)爆int变成-2147483648了)

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
typedef long long LL;

struct node
{
    int id;LL d;
};
struct cmd
{
    bool operator()(node n1,node n2)
    {
        return (n1.d==n2.d)?(n1.id>n2.id):(n1.d>n2.d);
    }
};
priority_queue<node,vector<node>,cmd>q,d;
LL c[210000],s[210000];int l[210000],r[210000];

int main()
{
    int n,m;node x;
    scanf("%d%d",&n,&m);
    scanf("%lld",&s[1]);
    for(int i=1;i<n;i++)
    {
        scanf("%lld",&s[i+1]);c[i]=s[i+1]-s[i];
        x.id=i;x.d=c[i];q.push(x);
        l[i]=i-1;
        r[i]=i+1;
    }
    r[0]=1;c[0]=~(1<<31);
    l[n]=n-1;c[n]=~(1<<31);
    
    LL ans=0;
    for(int i=1;i<=m;i++)
    {
        node n1,n2;
        while(1)
        {
            n1=q.top();
            if(d.empty()==true){q.pop();break;}
            n2=d.top();
            if(n1.d==n2.d&&n1.id==n2.id)
            {
                q.pop();n1=q.top();
                if(d.empty()==true)break;
                d.pop();n2=d.top();
            }
            else {q.pop();break;}
        }
        
        ans+=n1.d;
        int L=l[n1.id],R=r[n1.id];
        
        node de;
        de.id=L,de.d=c[L];d.push(de);
        de.id=R,de.d=c[R];d.push(de);
        
        node in;
        in.id=n1.id,in.d=c[L]+c[R]-n1.d;q.push(in);
        
        c[n1.id]=c[L]+c[R]-n1.d;
        l[n1.id]=l[L];r[l[L]]=n1.id;
        r[n1.id]=r[R];l[r[R]]=n1.id;
    }
    printf("%lld\n",ans);
    return 0;
}

 

posted @ 2018-03-25 10:18  AKCqhzdy  阅读(160)  评论(0编辑  收藏  举报